Tuesday, August 10, 2021

Lemay Lesson 19: Streams and I/O

Table of Contents

1. Introduction
2. Blaugust: Go on a Math Walk
3. Links to Other Bloggers: Bear St. Michael
4. Links to Other Bloggers: Sara(h) Season
5. A Rapoport Geometry Problem
6. Another Rapoport Geometry Problem
7. Lemay Lesson 19: Streams and I/O
8. Coding Using I/O
9. Politics: California Governor Recall Election
10. Conclusion

Introduction

OK, I've made my final decision regarding the blog calendar -- in particular, which school district I'll be following as I count the days.

I've chosen to follow the blog calendar for my LA County district -- believe it or not. Recall that earlier this summer, I wasn't sure whether I'd even be working in LA County this year -- and indeed, as of now I'm still not sure.

But as you might recall, school in my LA County district usually starts on a Wednesday -- in other words, tomorrow -- while my Orange County districts start next week. And so if I end up not working in LA County, it will be easier for me to take a few days off from blogging and wait for the OC calendars to catch up. It's better than doing the reverse -- skip days in the count if I start out with the OC calendar and suddenly decide to switch to LA County.

Anyway, due to today's last-minute decision, this is now suddenly my last post of the summer. I'll do one last day of coding in Java -- and it's one I've been looking forward to. To those who aren't familiar with C++, the word "streams" sounds mysterious, but I know what it really means -- input and output.

Blaugust: Go on a Math Walk

Let's get to today's Blaugust topic. Since today's date is the tenth, we'll just take the tenth topic from Shelli's old list from 2019.

  • Go on a “math walk” - take a photo to share with us… What do you notice? What do you wonder?  How could you use this photo in your classroom

Oops -- as you already know from previous years, I don't have a camera or smartphone to be able to take the photos with. And so any challenge topic involving photography is already eliminated for me.

But what exactly does Shelli mean by "math walk" anyway? I often see on Twitter math problems drawn on the street in chalk by young children. I really did take a short walk around the block today, and sure enough, I saw some numbers written in chalk on the walkway to a house. The numbers are written in boxes in a vertical column:

3
4
2? (I'm not quite sure!)
? (I can't tell what this is at all)
?
1
1
1
1
1

I don't know this family at all, and at this point a car pulled up, so I had to walk away at this point or be accused of loitering. It wasn't as if I could ask them what the significance of these numbers are. So that answers Shelli's question -- I notice the stack of numbers and wonder what they are for.

Probably, the chalk math problems I see on Twitter are posted by the young children of math teachers, who deliberately ask their children to do math on the sidewalk. Since I don't have any young children (as I've stated often on the blog), I had to walk around the block to find sidewalk math. Oh -- and directly across the street from the mysterious numbers is some other chalk writing. I easily recognize one of the words written there on the sidewalk -- "ART."

This is the only "math walk" I participated in today. But I did walk around to some mathematically significant points over the summer, so these could count as "math walks."

Earlier on the blog, I've discussed the Degree Confluence Project, and how I sometimes walk to the LA County confluence at 34 degrees N, 118 degrees W:

https://confluence.org/confluence.php?lat=34&lon=-118

Note that at the time of the last official visit to the confluence (Christmas Adam 2017 by a Russian father and son), there was a "parking spot" near the point (and many of the previous visitors have mentioned the parking spot as well).

But unfortunately, that parking spot no longer exists. First, a "No Parking" sign was placed there -- and then a little later, a fence was placed there. No one has made an official visit to the confluence since the fence blocked the old parking spot.

And so last week, I tried to find the closest place I could park (no questions asked) near the confluence and walk. Well, in Hacienda Heights, off of Turnbull Canyon Road, is a certain street called Orange Grove Avenue. On that street are Orange Grove Middle School and Orange Grove Park, so this is a valid public parking spot.

Interestingly enough, there is a compass rose painted on the ground in the park. And considering that the park address is 14517 while the address of the house at the confluence is 14478, it's possible that the north-south line of this compass lies right on the 118th Meridian West, perhaps at latitude 34 degrees 1 minute North -- that is, about one mile north of the confluence.

Unfortunately, I can't just walk one mile south to the confluence. Instead, I must start out by going east on Orange Grove. In fact, there's another possible parking spot to shorten the distance slightly -- in front of a hiking area. I don't enter the hiking area -- that trail takes us too far south and is also too steep, taking us to a higher elevation than the confluence. Still, it's possible to park there -- as long as the trail is open, no one can prove that I'm not on the trail.

I take Orange Grove to Las Tunas, then to Avocado, and then to Oak Canyon Drive. All of these are right turns. The walking distance each way is about 1.3 miles -- once I reach Oak Canyon, it's about 0.6 miles to the confluence. There's about a 300-foot rise in elevation, with most of the ascent on Las Tunas and Avocado.

Perhaps one of these days I'll contribute to the Degree Confluence Project -- while 34N, 118W is one of the most visited confluences, no one has visited since the removal of the parking spot, so maybe I should come in and let others know how to hike there due to the parking problem. And it's been years since I've travelled anywhere -- before I knew what a confluence was. And so I've never been to the other confluences besides 34N, 118W.

There's another mathematically/geographically significant walk that I've taken lately. Many people don't know that the flattest state is Florida -- its highest point is a mere 345 feet above sea level. There are Miami skyscrapers that are double this height. And in California, it's possible to walk from the shore to a point above 345 feet in less than one hour.

And so last month, I took such a walk. (There are many places along the California coastline where such a walk is possible.) I completed the hike, then declared that I'd walked the entire state of Florida in under an hour (vertically, that is).

Those are just two of what I'd consider to be possible "math walks." Perhaps another way to take a mathematical walk is to treat the city as a coordinate plane, where addresses are listed by a number followed by N, S, E, or W. In many cities, the origin is placed near city hall -- this includes the city of LA, which starts at 100 at First and Main.

https://eng2.lacity.org/techdocs/permits/11_2.pdf

An interesting walk would be along the line y = x -- not literally, since that would cut across blocks. But we might start at 100 First Street and go to 200 W (or E) 2nd St., then 300 3rd St., and so on. We might make it all the way to 1000 before getting tired. An alternative (since parking downtown is expensive) would be to figure what the closest point to the origin along y = x where parking is free, and then walk from that point back to First and Main. It's interesting to see exactly how long each block really is.

Links to Other Bloggers: Bear St. Michael

Once again, there is no official Blaugust challenge this year. But there's one author, linked from Shelli's blog, who has posted almost everyday this month -- Bear St. Michael:

https://questionsaboutmath.blogspot.com/

St. Michael is doing his own side-along reading this month:

As part of a summer professional reading group, some colleagues and I elected to read Grading for Equity, by Joe Feldman. It's a big topic, so I wanted an excuse to do some reflective writing on it, so I can try to understand it more deeply. Fortunately, Feldman wrote some "Questions to Consider" at the end of each chapter, and so I hope to use those to guide regular reflections.

As the title implies, the book is all about more effective ways to grade and evaluate students. But St. Michael himself questions whether we should even give grades at all:

https://questionsaboutmath.blogspot.com/2021/08/grading-for-equity-reflection-questions_10.html

  • Judge? Or coach? At one point, Feldman discusses the difference between "feedback" and "grading" as the difference between what a "coach" does, and what a "judge" does. I won't go into it, but I think that's a really meaningful way to think about it. And I'm pretty sure that I'm trying to go the way of "teacher-as-coach." And then I only engage in "teacher-as-judge" to the extent that I'm required to engage in the system of grades by external factors. This feeling is a big part of why I increasingly consider myself a grade-abolitionist, and hope to learn more in the future about "un-grading."

Naturally, most traditionalists would be opposed to abolishing grades entirely. They'd argue that if we didn't give grades, most students would leave every assignment blank. And as evidence, they point to the pandemic, especially its first few months from March to June 2020. Many schools stopped giving grades during this time -- and many students responded by doing absolutely no work during this first stint of distance learning.

Links to Other Bloggers: Sara(h) Season

Blaugust is also known as Sara(h) season -- that is, the time of the year when the two famous math teacher-bloggers, Sarah Carter and Sara Vanderwerf -- post their favorite opening week activities. And many math teachers would blog or tweet pictures of their students being engaged and having fun with the Sara(h) activities.

Here is a link to Sarah Carter's first day of school post. Her students return tomorrow, and of course she has planned a full day of activities:

https://mathequalslove.net/first-day-of-school-activities-2021/

Sara Vanderwerf, on the other hand, has made zero posts so far in calendar year 2021. She did post last year around Week 1 of school regarding one of her opening week activities:

https://www.saravanderwerf.com/the-100-number-task-during-a-pandemic-is-it-possible/

Both Sara(h)s write about how to adapt their activities to the ongoing pandemic.

A Rapoport Geometry Problem

Today on her Daily Epsilon on Math 2021, Rebecca Rapoport writes:

What is the area of the shaded trapezoid?

As usual, all of the givens are in an unlabeled diagram, so I must provide the labeling. Let's label the given trapezoid as ABCD, with AB | | DC. There is also a circle drawn such that A and D are on the circle, and BC is tangent to it. Side AB is longer than CD -- in fact, there exists a point E on AB such that E is on the circle, while no such point lies on CD. Finally, AE = 3, BE = DC = 1, Angle B is right.

Technically speaking, it isn't stated that AB | | DC. We are given that ABCD is a trapezoid, and so two of its sides are parallel, but we don't know which ones. But AD and BC appear to be not even close to parallel, and so it's considered valid to assume that AB and DC are the parallel sides. Since Angle B is a right angle, this also makes C a right angle.

We're asked to find the area of this trapezoid, so we should already be thinking in terms of the trapezoid area formula, (1/2)h(b_1 + b_2). Notice that the two bases are essentially given -- DC is 1, while AB is found as 1 + 3 = 4. So the meat of this problem is to find the height of the trapezoid -- and that, as it turns out, is a bit tricky. It took me time to figure it out.

First, we consider Quadrilateral BCDE, with right angles B and C and sides BE = DC = 1. This is enough information to conclude that BCDE is a rectangle. (We've discussed this proof on the blog before, in the context of Saccheri quadrilaterals. First, Triangles EBC and DCB are congruent by SAS, and so CE = BD and Angles BCE = CBD by CPCTC. Thus the angles complementary to these, which are ECD and DBE, are also congruent. This is enough to conclude Triangles ECD and DBE to be congruent also by SAS, and so Angles CED and BDE are congruent by CPCTC. Then combining this with Angles BEC and CDB from the first congruent pair, we get Angle BED = CDE -- and since two of the angles of quad BCDE are right, this leaves 180 degrees for BED = CDE, and so each of those angles is also 90.)

With BED a right angle, this also makes the angle supplementary to it, AED, also a right angle. Notice that all of A, E, D lie on the circle, making this an inscribed right angle. Thus AD is a diameter -- and so let's label its midpoint O, in order to emphasize that this is the center of the circle.

Let's now label another point -- since BC is a tangent, let's call the point of tangency F. Now we look at the segment OF. It's clearly a radius of the circle -- but it's also a midsegment of the trapezoid. (To see why, we already know that O is the midpoint of AD. As for F on BC, first we notice that in OED -- isosceles since OE and OD are radii -- Angle OED = ODE. Combining this with the known right angles BED and CDE gives us Angle OEB = ODC. So Triangles OEB and ODC are congruent by SAS, leading to OB = OC by CPCTC. Of course OF = OF, and OF is perpendicular to BC by Radius-Tangent, and so we have Triangles OBF and OCF congruent by HL. Hence BF = CF -- and with O and F the midpoints of AD and BC respectively, OF is a midsegment.)

Recall that the length of the midsegment is the (1/2)(b_1 + b_2) that appears in the area formula -- and so the midsegment OF = (1 + 4)/2 = 5/2 -- and this, if you recall, is also the radius of the circle. And so we know that the diameter AD = 5.

Finally, we consider Triangle AED -- a right triangle with the right angle at E. It has leg AE = 3 and hypotenuse AD = 5, and so ED = 4 by the Pythagorean Theorem. And since ED is perpendicular to both bases of the trapezoid, ED = 4 is the sought-after height that we've been working hard to find.

We put this into the formula -- multiplying the midsegment by the height gives (5/2)4 = 10. Therefore the desired area is 10 -- and of course, today's date is the tenth.

As I check this problem out on Twitter, one respondent saved some time by using Power of a Point -- the power of point B is AB * EB = 4 * 1 = 4, and this is also the square of the tangent BF, hence 2. So we get BF = 2 much more easily, but there is still work to get ED twice as long as BF. The one who tweeted this solution also saved some time by noting that radius OF must bisect ED (from one of our theorems from Lesson 15-1 of the U of Chicago text).

Another Rapoport Geometry Problem

Here's another recent problem from the calendar:

How many convex deltahedra are there?

This is a research problem -- we can't even begin unless we know what a deltahedron is. The word sounds like "polyhedron," so it's probably some 3D figure:

https://mathworld.wolfram.com/Deltahedron.html

A deltahedron is a polyhedron whose faces are congruent equilateral triangles (Wells 1986, p. 73). Note that polyhedra whose faces could be triangulated so as to be composed of coplanar equilateral triangles sharing an edge (such as the truncated tetrahedron, whose hexagonal faces could be considered as six conjoined equilateral triangles) are not allowed.

Thus the "delta" here means equilateral triangle -- the shape of that Greek letter. It has nothing to do with the "delta variant" of the coronavirus that we've been hearing about so much lately.

We can see at the link that there are eight convex deltahedra. Three of these are already familiar -- the tetrahedron, octahedron, and icosahedron.

Two more are "bipyramids" (that is, two pyramids joined at the base) -- triangular and pentagonal. So you might wonder, why aren't there other bipyramids, such as square or hexagonal? Well, there already is a square bipyramid -- it's also known as an "octahedron." As for a hexagonal bipyramid, it would have to be flat, since six equilateral triangles make a flat hexagon (and flat sides are expressly forbidden by the definition above). We can't have a hexagonal bipyramid unless we stretch the faces -- at which point they'd no longer be equilateral.

Lemay Lesson 19: Streams and I/O

Here is the link to today's lesson:

http://101.lv/learn/Java/ch19.htm

Lesson 19 of Laura Lemay's Teach Yourself Java in 21 Days! is called "Streams and I/O." Here's how the chapter begins:

The package java.io, part of the standard Java class library, provides a large number of classes designed for handling input and output to files, network connections, and other sources. These I/O classes are known as streams, and provide functionality for reading and writing data in various ways. You got a glimpse of these classes on Day 14, "Windows, Networking, and Other Tidbits," when we opened a network connection to a file and read the contents into an applet.

Once again, I've been looking forward to learning more about input and output, so let's go.

stream is a path of communication between the source of some information and its destination. This information can come from a file, the computer's memory, or even from the Internet. In fact, the source and destination of a stream are completely arbitrary producers and consumers of bytes, respectively-you don't need to know about the source of the information when reading from a stream, and you don't need to know about the final destination when writing to one.

Once again, this is just like C++.

All the classes you will learn about today are part of the package java.io. To use any of these classes in your own programs, you will need to import each individual class or to import the entire java.io package, like this:

import java.io.InputStream;
import java.io.FilteredInputStream;
import java.io.FileOutputStream;

import java.io.*;

All the methods you will explore today are declared to throw IOExceptions. This new subclass of Exception conceptually embodies all the possible I/O errors that might occur while using streams. Several subclasses of it define a few, more specific exceptions that can be thrown as well. For now, it is enough to know that you must either catch an IOException, or be in a method that can "pass it along," to be a well-behaved user of streams.

OK, this is one difference between Java and C++. Stream methods in C++ don't necessarily have to throw exceptions, although it's a good idea. But these methods in Java do. That's why we had to wait until learning exceptions in Lesson 17 before we could learn about streams, while a C++ user can learn streams without knowing exceptions.

Lemay begins with input streams:

Input streams are streams that allow you to read data from a source. These include the root abstract class InputStream, filtered streams, buffered streams, and streams that read from files, strings, and byte arrays.

And then we learn how these input streams can read our data:

The most important method to the consumer of an input stream is the one that reads bytes from the source. This method, read(), comes in many flavors, and each is demonstrated in an example in today's lesson.

Here's the first form of read():

InputStream  s      = getAnInputStreamFromSomewhere();
byte[]       buffer = new byte[1024];   // any size will do

if (s.read(buffer) != buffer.length)
    System.out.println("I got less than I expected.");

The author tells us that in addition to reading the data and storing it in buffer, the read() method also returns a value -- the number of bytes read. If we're at the end of the file, it returns -1 -- and she explains another difference between Java and C (including C++) here:

Don't forget that, unlike in C, the -1 case in Java is not used to indicate an error. Any I/O errors throw instances of IOException (which you're not catching yet). You learned on Day 17, "Exceptions," that all uses of distinguished values can be replaced by the use of exceptions, and so they should. The -1 in the last example is a bit of a historical anachronism. You'll soon see a better approach to indicating the end of the stream using the class DataInputStream.

We move on to some other input methods:

skip()

What if you want to skip over some of the bytes in a stream, or start reading a stream from other than its beginning? A method similar to read() does the trick:

if (s.skip(1024) != 1024)
    System.out.println("I skipped less than I expected.");

available()

If for some reason you would like to know how many bytes are in the stream right now, you can ask the following:

if (s.available() < 1024)
    System.out.println("Too little is available right now.");

mark() and reset()

Some streams support the notion of marking a position in the stream and then later resetting the stream to that position to reread the bytes there. Clearly, the stream would have to "remember" all those bytes, so there is a limitation on how far apart in a stream the mark and its subsequent reset can occur. There's also a method that asks whether the stream supports the notion of marking at all. Here's an example:

InputStream  s = getAnInputStreamFromSomewhere();

if (s.markSupported()) {    // does s support the notion?
    . . .        // read the stream for a while
    s.mark(1024);
    . . .        // read less than 1024 more bytes
    s.reset();
    . . .        // we can now re-read those bytes
} else {
    . . .                   // no, perform some alternative
}

close()

Because you don't know what resources an open stream represents, nor how to deal with them properly when you're finished reading the stream, you should (usually) explicitly close down a stream so that it can release these resources. Of course, garbage collection and a finalization method can do this for you, but what if you need to reopen that stream or those resources before they have been freed by this asynchronous process? At best, this is annoying or confusing; at worst, it introduces an unexpected, obscure, and difficult-to-track-down bug. Because you're interacting with the outside world of external resources, it's safer to be explicit about when you're finished using them:

InputStream  s = alwaysMakesANewInputStream();

try {
    . . .     // use s to your heart's content
} finally {
    s.close();
}

ByteArrayInputStream

The "inverse" of some of the previous examples would be to create an input stream from an array of bytes. This is exactly what ByteArrayInputStream does:

byte[]  buffer = new byte[1024];

fillWithUsefulData(buffer);

InputStream  s = new ByteArrayInputStream(buffer);

This last one is a lot different from anything I know from C++. Most of the time, the istreams in C++ are files -- I don't think we can make a C++ array into a stream. The author comments:

Finally, you've seen your first examples of the creation of a stream. These new streams are attached to the simplest of all possible sources of data: an array of bytes in the memory of the local computer.

FileInputStream

One of the most common uses of streams, and historically the earliest, is to attach them to files in the file system. Here, for example, is the creation of such an input stream on a UNIX system:

InputStream  s = new FileInputStream("/some/path/and/fileName");

OK, that's more like what I was expecting -- files as input streams. The author warns us that we can't use files as input streams in applets.

FilterInputStream

This "abstract" class simply provides a "pass-through" for all the standard methods of InputStream. (It's "abstract," in quotes, because it's not technically an abstract class; you can create instances of it. In most cases, however, you'll use one of the more useful subclasses of FilterInputStream instead of FilterInputStream itself.) FilterInputStream holds inside itself another stream, by definition one further "down" the chain of filters, to which it forwards all method calls. It implements nothing new but allows itself to be nested:

InputStream        s  = getAnInputStreamFromSomewhere();
FilterInputStream  s1 = new FilterInputStream(s);
FilterInputStream  s2 = new FilterInputStream(s1);
FilterInputStream  s3 = new FilterInputStream(s2);

... s3.read() ...

Let's skip down to data input streams, since those are important -- we use streams to input data:

DataInputStream

All the methods that instances of this class understand are defined in a separate interface, which both DataInputStream and RandomAccessFile (another class in java.io) implement. This interface is general-purpose enough that you might want to use it yourself in the classes you create. It is called DataInput.

The DataInput Interface

When you begin using streams to any degree, you'll quickly discover that byte streams are not a really helpful format into which to force all data. In particular, the primitive types of the Java language embody a rather nice way of looking at data, but with the streams you've been defining thus far in this book, you could not read data of these types. The DataInput interface specifies a higher-level set of methods that, when used for both reading and writing, can support a more complex, typed stream of data. Here are the methods this interface defines:

void  readFully(byte[]  buffer)                           throws IOException;
void  readFully(byte[]  buffer, int  offset, int  length) throws IOException;
int   skipBytes(int n)                                    throws IOException;

boolean  readBoolean()       throws IOException;
byte     readByte()          throws IOException;
int      readUnsignedByte()  throws IOException;
short    readShort()         throws IOException;
int      readUnsignedShort() throws IOException;
char     readChar()          throws IOException;
int      readInt()           throws IOException;
long     readLong()          throws IOException;
float    readFloat()         throws IOException;
double   readDouble()        throws IOException;

String   readLine()          throws IOException;
String   readUTF()           throws IOException;

And finally, we look at an important common exception -- end of file:'

EOFException

One final point about most of DataInputStream's methods: When the end of the stream is reached, the methods throw an EOFException. This is tremendously useful and, in fact, allows you to rewrite all the kludgey uses of -1 you saw earlier today in a much nicer fashion:

DataInputStream  s = new DataInputStream(getAnInputStreamFromSomewhere());

try {
    while (true) {
        byte  b = (byte) s.readByte();
        . . .    // process the byte b
    }
} catch (EOFException e) {
    . . .    // reached end of stream
} finally {
  s.close();
}

PushbackInputStream

The filter stream class PushbackInputStream is commonly used in parsers, to "push back" a single character in the input (after reading it) while trying to determine what to do next-a simplified version of the mark() and reset() utility you learned about earlier. Its only addition to the standard set of InputStream methods is unread(), which, as you might guess, pretends that it never read the byte passed in as its argument, and then gives that byte back as the return value of the next read().

OK, so let's get to the first -- and only -- listing of the lesson:

Listing 19.1. A simple line reader.
 1:import java.io.*;
 2:
 3:public class  SimpleLineReader {
 4:    private FilterInputStream  s;
 5:
 6:    public  SimpleLineReader(InputStream  anIS) {
 7:        s = new DataInputStream(anIS);
 8:    }
 9:
10:    . . .    // other read() methods using stream s
11:
12:    public String  readLine() throws IOException {
13:        char[]  buffer = new char[100];
14:        int     offset = 0;
15:        byte    thisByte;
16:
17:        try {
18:loop:        while (offset < buffer.length) {
19:                switch (thisByte = (byte) s.read()) {
20:                    case '\n':
21:                        break loop;
22:                    case '\r':
23:                        byte  nextByte = (byte) s.read();
24:
25:                        if (nextByte != '\n') {
26:                            if (!(s instanceof PushbackInputStream)) {
27:                                s = new PushbackInputStream(s);
28:                            }
29:                            ((PushbackInputStream) s).unread(nextByte);
30:                        }
31:                        break loop;
32:                    default:
33:                        buffer[offset++] = (char) thisByte;
34:                        break;
35:                }
36:            }
37:        } catch (EOFException e) {
38:            if (offset == 0)
39:                return null;
40:        }
41:          return String.copyValueOf(buffer, 0, offset);
42:     }
43:}

I did end up fixing one error in Lemay here -- her first line is import java.io where she clearly means import java.io.* here.

Of course, there's no output here -- the other read methods are missing, there's no main method, and most importantly, there's no input stream.

Lemay now moves on to output streams:

An output stream is the reverse of an input stream; whereas with an input stream you read data from the stream, with output streams you write data to the stream. Most of the InputStream subclasses you've already seen have their equivalent OutputStream brother classes. If an InputStream performs a certain operation, the brother OutputStream performs the inverse operation. You'll see more of what this means soon.

Just as the primary task of a input stream is to read, the primary task of an output stream is to write:

The most important method to the producer of an output stream is the one that writes bytes to the destination. This method, write(), comes in many flavors, each demonstrated in the following examples:

OutputStream  s      = getAnOutputStreamFromSomewhere();
byte[]        buffer = new byte[1024];    // any size will do

fillInData(buffer);    // the data we want to output
s.write(buffer);

flush()

Because you don't know what an output stream is connected to, you might be required to "flush" your output through some buffered cache to get it to be written (in a timely manner, or at all). OutputStream's version of this method does nothing, but it is expected that subclasses that require flushing (for example, BufferedOutputStream and PrintStream) will override this version to do something nontrivial.

close()

Just like for an InputStream, you should (usually) explicitly close down an OutputStream so that it can release any resources it may have reserved on your behalf. (All the same notes and examples from InputStream's close() method apply here, with the prefix In replaced everywhere by Out.)

All output streams descend from the abstract class OutputStream. All share the previous few methods in common.

ByteArrayOutputStream

The inverse of ByteArrayInputStream, which creates an input stream from an array of bytes, is ByteArrayOutputStream, which directs an output stream into an array of bytes:

OutputStream  s = new ByteArrayOutputStream();

s.write(123);
. . .

In fact, many of the input streams that we've seen have "inverse" output streams, and so we don't need to keep cutting and pasting all of them.

Processing a File

One of the most common idioms in file I/O is to open a file, read and process it line-by-line, and output it again to another file. Here's a prototypical example of how that would be done in Java:

DataInput   aDI = new DataInputStream(new FileInputStream("source"));
DataOutput  aDO = new DataOutputStream(new FileOutputStream("dest"));
String      line;

while ((line = aDI.readLine()) != null) {
    StringBuffer  modifiedLine = new StringBuffer(line);

    . . .      // process modifiedLine in place
    aDO.writeBytes(modifiedLine.toString());
}
aDI.close();
aDO.close();

PrintStream

You may not realize it, but you're already intimately familiar with the use of two methods of the PrintStream class. That's because whenever you use these method calls:

System.out.print(. . .)
System.out.println(. . .)

you are actually using a PrintStream instance located in System's class variable out to perform the output. System.err is also a PrintStream, and System.in is an InputStream.

This is something that happens in C++ as well. In fact, the first C++ program that we learn, the Hello World program, usually contains the following line:

cout << "Hello World!\n";

It's not until much later that we learn that this cout is actually a stream -- and it can do almost anything that any other ostream can do. So of course the same is true in Java -- System.out is a print screen, and so its primary task is to print to standard output, the screen.

Lemay's final topic in this lesson is object serialization:

A topic to streams, and one that will be available in the core Java library with Java 1.1, is object serialization. Serialization is the ability to write a Java object to a stream such as a file or a network connection, and then read it and reconstruct that object on the other side. Object serialization is crucial for the ability to save Java objects to a file (what's called object persistence), or to be able to accomplish network-based applications that make use of Remote Method Invocation (RMI)-a capability you'll learn more of on Day 27, "The Standard Extension APIs."

Here's a simple example from the object serialization specification that writes a date to a file (actually, it writes a string label, "Today", and then a Date object):

FileOutputStream f = new FileOutputStream("tmp");
ObjectOutput  s  =  new  ObjectOutputStream(f);
s.writeObject("Today");
s.writeObject(new Date());
s.flush();

To deserialize the object (read it back in again), use this code:

FileInputStream in = new FileInputStream("tmp");
ObjectInputStream s = new ObjectInputStream(in);
String today = (String)s.readObject();
Date date = (Date)s.readObject();

Coding Using I/O

I want to try a simple input/output program. Instead of input files, let's just use standard input -- in other words, the keyboard:

import java.io.*;
public class CylinderVolume {

double Volume (int r) {
final double pi = 3.1415926535897932;
return 4.0 / 3.0 * pi * r * r * r;
}
public static void main (String args []) {
byte [] radius = new byte[1];
CylinderVolume cv = new CylinderVolume();
final int zero = 48; //ASCII code for "0"
try {
System.out.println("Radius?");
System.in.read(radius);
System.out.print("Volume:");
System.out.println(cv.Volume((int)radius[0]-zero));
} catch (IOException e) {
System.out.println("Error!");
}
}
}

This program works, but it's messy -- it only reads one byte at a time, so we can only find the volume for radii from 1 to 9. I couldn't figure out how to get it to read more than one byte -- so in particular, it can't read a height into a second variable. Thus it actually finds the volume of a sphere -- I was too lazy to change the filename from CylinderVolume to SphereVolume. So while I finally did some input, this proves that I still have much to learn about it.

Politics: California Governor Recall Election

I try to keep politics out of my school year posts -- since this is my last official summer post, it's my last chance to discuss politics. I live in California, and many of you outside our state might be aware that there is a recall election coming up on September 14th. I feel that I might as well try to explain what is going on with this election.

Why is Governor Gavin Newsom facing a recall election. The simplest explanation is this -- many people feel that Newsom has implemented many restrictions in order to keep us safe, but then he hypocritically breaks them himself. I won't discuss the main example of this hypocrisy in much detail -- you can Google the terms  Newsom French Laundry to learn more about this. But there's one example that's directly related to schools and education, and this is what I wish to discuss here on the blog.

Remember that Newsom had implemented a four-tier system for openings, including schools. Those counties in the purple tier must have distance learning only, but those in the red and other tiers can open for some in-person instruction. Many urban or suburban counties dropped from purple to red around October 2020 -- including Sacramento, where the capital is.

But not all schools reopened right away. Some schools did open in October, but others preferred to wait until the start of the second quarter, trimester, or semester. It's generally believed that teacher unions are a factor -- public schools with strong unions would wait until the start of a term. This includes San Juan Unified, where the capital is -- it opted to wait until the second semester in January. Private schools without strong unions tended to open in October -- this includes the private school where Newsom's children attend. He has four children -- the oldest is starting sixth grade this year, while the youngest is starting kindergarten.

Unfortunately, in November, the third wave of coronavirus surged, and counties that had entered the red tier regressed to purple. But schools that have opened before the third wave could remain open. Thus San Juan Unified, which was waiting for January, had to stay closed even longer, while the private school that the young Newsoms attended stayed open.

I believe that most parents don't know what quarters or trimesters are. In particular, middle schools follow either calendar, but most parents couldn't tell you which one their school follows (except for those parents who work for the district). They only know that report cards come when they come. And so they don't understand why schools should wait for the next quarter or trimester to reopen -- especially parents of elementary school children (around the Newsoms' ages), who are the most likely to prefer in-person instruction. They don't think, "There's only a week or so left in the trimester, so let's just reopen at the second trimester." They see, "The young Newsoms are going to school and my kids aren't, and I blame Newsom."

Parents do respect long breaks, so they might validly say "There's only one week until Thanksgiving or winter break, so let's wait until after break to reopen" as opposed to the trimester. Notice that San Juan was waiting for the second semester, which is after the long winter break. Then again, October was much too early for parents to say "Let's just wait until after break to reopen."

And then this was followed a few weeks later by the French Laundry scandal. French Laundry was the straw that broke the camel's back, but the frustration over hypocrisy began with the schools.

What should Newsom have done with the schools? In past posts, I wrote of Presidential Consistency and the idea that what's good for the our leaders' children is good for the rest of us. So we might consider Gubernatorial Consistency here.

Here's what Gubernatorial Consistency might have looked like -- on the very first October day that his children attended in-person private school, Newsom announces a change to the four-tier system. In particular, schools are immediately allowed to reopen even in the purple tier. This applies to all schools serving students of the same ages as the young Newsoms at the time (that is, PK-5). Secondary schools serving students older than the Newsoms will stay closed in the purple tier (even if they reopened, many parents would opt out and keep their teens at home anyway).

If a district chooses a hybrid schedule but the Newsoms' private school is open five full days, then parents would blame the district -- not Newsom. If a union chooses to wait until the next term to reopen, then parents would blame the union -- not Newsom. And if a county (say LA County) decides to keep schools closed even after Newsom allows them to open, then parents would blame the county -- not Newsom. By allowing purple-tier elementary schools to reopen in October 2020 (and by avoiding French Laundry), I believe that Newsom faces no recall.

The last successful recall election occurred in 2003, when Arnold Schwarzenegger replaced the recalled Gray Davis. I was a grad student at UCLA at the time. I couldn't decide upon any of the candidates, and so I voted "No" on the recall and left the candidate blank. I'd only have voted "Yes" if I had decisively chosen a candidate to replace Davis. On the other hand, there was a move by Lt. Gov. Cruz Bustamente to have voters say "No" on the recall yet choose him as the replacement. I didn't do this either -- if I was going to mark any candidate, then I would have voted "Yes."

The same is true for this year's recall. I'll vote "No" on the recall, and no candidate, unless one of the candidates suddenly stands out to me. Then I'll vote "Yes" and for that candidate. Oh, and if even that happens and I vote for a candidate, I won't announce that candidate on the blog (or Twitter), so don't expect me to endorse any candidate here. I admit that as I said earlier in this post, I have no young children, and my middle school reopened in October, and so I can't truly feel the frustration of those parents of elementary schools that stayed closed (otherwise I might have a replacement candidate now).

During the past presidential election, I came up with a color spectrum to show the partisan leanings of the various candidates. Blue is a mainstream Democrat, while red is mainstream Republican. Those who are more moderate in each party is a particular shade of purple. Meanwhile, Democrats to the left of the mainstream are shades of green (that is, approaching the Green Party), while Republicans to the right of the mainstream are shades of yellow (approaching the Libertarian Party).

Newsom is the Democratic incumbent, so he is blue. Kevin Paffrath is a moderate Democrat, and so would be some shade of bluish-purple. (He is a Millennial who would become the youngest governor, edging out Ron DeSantis of the flattest state of Florida, a Gen Xer.)

Most of the Republicans running in the recall are pro-Trump, and so are red, since I consider the last standard bearer of the party to be red. (An argument was made that Trump, at the time of his election, wasn't part of the GOP establishment, making him more orange than red. But his views are more in line with the mainstream now, and so he and his supporters are red.) Some more libertarian-leaning candidates might still be considered some shade of reddish-orange or yellow (such as Larry Elder).

Conclusion

And so that concludes my final post of the summer. My first school year post, which will follow my LA County school district, will be tomorrow.

1 comment:

  1. Thanks for writing this excellent blog for us. I have gained good stuff from this website. I am looking forward to your next blog.

    If you searching for a legit financial service .Check it out. Link below.
    Buy a card
    legit dark web
    Unclaimed Mystery Box
    legit PayPal transfer dark web
    dark web financial services .

    Not only that, but I am happy to share this post with my friends. Keep it up...

    ReplyDelete