Friday, October 30, 2009

Section 5.5. Operators










5.5. Operators


Numeric types support a wide variety of operators, ranging from the standard type of operators to operators created specifically for numbers, and even some that apply to integer types only.



5.5.1. Mixed-Mode Operations


It may be hard to remember, but when you added a pair of numbers in the past, what was important was that you got your numbers correct. Addition using the plus ( + ) sign was always the same. In programming languages, this may not be as straightforward because there are different types of numbers.


When you add a pair of integers, the + represents integer addition, and when you add a pair of floating point numbers, the + represents double-precision floating point addition, and so on. Our little description extends even to non-numeric types in Python. For example, the + operator for strings represents concatenation, not addition, but it uses the same operator! The point is that for each data type that supports the + operator, there are different pieces of functionality to "make it all work," embodying the concept of overloading.


Now, we cannot add a number and a string, but Python does support mixed mode operations strictly between numeric types. When adding an integer and a float, a choice has to be made as to whether integer or floating point addition is used. There is no hybrid operation. Python solves this problem using something called numeric coercion. This is the process whereby one of the operands is converted to the same type as the other before the operation. Python performs this coercion by following some basic rules.


To begin with, if both numbers are the same type, no conversion is necessary. When both types are different, a search takes place to see whether one number can be converted to the other's type. If so, the operation occurs and both numbers are returned, one having been converted. There are rules that must be followed since certain conversions are impossible, such as turning a float into an integer, or converting a complex number to any non-complex number type.


Coercions that are possible, however, include turning an integer into a float (just add ".0") or converting any non-complex type to a complex number (just add a zero imaginary component, e.g., "0j"). The rules of coercion follow from these two examples: integers move toward float, and all move toward complex. The Python Language Reference Guide describes the coerce() operation in the following manner.


  • If either argument is a complex number, the other is converted to complex;

  • Otherwise, if either argument is a floating point number, the other is converted to floating point;

  • Otherwise, if either argument is a long, the other is converted to long;

  • Otherwise, both must be plain integers and no conversion is necessary (in the upcoming diagram, this describes the rightmost arrow).


The flowchart shown in Figure 5-1 illustrates these coercion rules.




Figure 5-1. Numeric coercion








Automatic numeric coercion makes life easier for the programmer because he or she does not have to worry about adding coercion code to his or her application. If explicit coercion is desired, Python does provide the coerce() built-in function (described later in Section 5.6.2).


The following is an example showing you Python's automatic coercion. In order to add the numbers (one integer, one float), both need to be converted to the same type. Since float is the superset, the integer is coerced to a float before the operation happens, leaving the result as a float:


>>> 1 + 4.5
5.5




5.5.2. Standard Type Operators


The standard type operators discussed in Chapter 4 all work as advertised for numeric types. Mixed-mode operations, described above, are those which involve two numbers of different types. The values are internally converted to the same type before the operation is applied.


Here are some examples of the standard type operators in action with numbers:


>>> 5.2 == 5.2
True
>>> -719 >= 833
False
>>> 5+4e >= 2-3e
True
>>> 2 < 5 < 9 # same as ( 2 < 5 )and ( 5 < 9 )
True
>>> 77 > 66 == 66 # same as ( 77 > 66 )and ( 66 == 66 )
True
>>> 0. < -90.4 < 55.3e2 != 3 < 181
False
>>> (-1 < 1) or (1 < -1)
True




5.5.3. Numeric Type (Arithmetic) Operators


Python supports unary operators for no change and negation, + and -, respectively; and binary arithmetic operators +, -, *, /, %, and **, for addition, subtraction, multiplication, division, modulo, and exponentiation, respectively. In addition, there is a new division operator, //, as of Python 2.2.








Division

Those of you coming from the C world are intimately familiar with classic divisionthat is, for integer operands, floor division is performed, while for floating point numbers, real or true division is the operation. However, for those who are learning programming for the first time, or for those who rely on accurate calculations, code must be tweaked in a way to obtain the desired results. This includes casting or converting all values to floats before performing the division.


The decision has been made to change the division operator in some future version of Python from classic to true division and add another operator to perform floor division. We now summarize the various division types and show you what Python currently does, and what it will do in the future.



Classic Division

When presented with integer operands, classic division truncates the fraction, returning an integer (floor division). Given a pair of floating-point operands, it returns the actual floating-point quotient (true division). This functionality is standard among many programming languages, including Python. Example:


>>> 1 / 2               # perform integer result (floor)
0
>>> 1.0 / 2.0 # returns actual quotient
0.5




True Division

This is where division always returns the actual quotient, regardless of the type of the operands. In a future version of Python, this will be the algorithm of the division operator. For now, to take advantage of true division, one must give the from__future__import division directive. Once that happens, the division operator ( / ) performs only true division:


>>> from __future__ import division
>>>
>>> 1 / 2 # returns real quotient
0.5
>>> 1.0 / 2.0 # returns real quotient
0.5




Floor Division

A new division operator ( // ) has been created that carries out floor division: it always truncates the fraction and rounds it to the next smallest whole number toward the left on the number line, regardless of the operands' numeric types. This operator works starting in 2.2 and does not require the __future__ directive above.


>>> 1 // 2     # floors result, returns integer
0
>>> 1.0 // 2.0 # floors result, returns float
0.0
>>> -1 // 2 # move left on number line
-1


There were strong arguments for as well as against this change, with the former from those who want or need true division versus those who either do not want to change their code or feel that altering the division operation from classic division is wrong.


This change was made because of the feeling that perhaps Python's division operator has been flawed from the beginning, especially because Python is a strong choice as a first programming language for people who aren't used to floor division. One of van Rossum's use cases is featured in his "What's New in Python 2.2" talk:


def velocity(distance, totalTime):
rate = distance / totalTime


As you can tell, this function may or may not work correctly and is solely dependent on at least one argument being a floating point value. As mentioned above, the only way to ensure the correct value is to cast both to floats, i.e., rate = float(distance) / float(totalTime). With the upcoming change to true division, code like the above can be left as is, and those who truly desire floor division can use the new double-slash ( // ) operator.


Yes, code breakage is a concern, and the Python team has created a set of scripts that will help you convert your code to using the new style of division. Also, for those who feel strongly either way and only want to run Python with a specific type of division, check out the -Qdivision_style option to the interpreter. An option of -Qnew will always perform true division while -Qold (currently the default) runs classic division. You can also help your users transition to new division by using -Qwarn or -Qwarnall.


More information about this big change can be found in PEP 238. You can also dig through the 2001 comp.lang.python archives for the heated debates if you are interested in the drama. Table 5.2 summarizes the division operators in the various releases of Python and the differences in operation when you import new division functionality.


Table 5.2. Division Operator Functionality

Operator

2.1.x and Older

2.2 and Newer (No Import)

2.2 and Newer (Import of division)

/

classic

classic

true

//

n/a

floor

floor






Modulus

Integer modulo is straightforward integer division remainder, while for float, it is the difference of the dividend and the product of the divisor and the quotient of the quantity dividend divided by the divisor rounded down to the closest integer, i.e.,x - (math.floor(x/y) * y), or





For complex number modulo, take only the real component of the division result, i.e., x - (math.floor((x/y).real) * y).




Exponentiation

The exponentiation operator has a peculiar precedence rule in its relationship with the unary operators: it binds more tightly than unary operators to its left, but less tightly than unary operators to its right. Due to this characteristic, you will find the ** operator twice in the numeric operator charts in this text. Here are some examples:


>>> 3 ** 2
9
>>> -3 ** 2 # ** binds tighter than - to its left
-9
>>> (-3) ** 2 # group to cause - to bind first
9
>>> 4.0 ** -1.0 # ** binds looser than - to its right
0.25


In the second case, it performs 3 to the power of 2 (3-squared) before it applies the unary negation. We need to use the parentheses around the "-3" to prevent this from happening. In the final example, we see that the unary operator binds more tightly because the operation is 1 over quantity 4 to the first power ¼1 or ¼. Note that 1 / 4 as an integer operation results in an integer 0, so integers are not allowed to be raised to a negative power (it is a floating point operation anyway), as we will show here:


>>> 4 ** -1
Traceback (innermost last):
File "<stdin>", line 1, in ?
ValueError: integer to the negative power




Summary

Table 5.3 summarizes all arithmetic operators, in shaded hierarchical order from highest-to-lowest priority. All the operators listed here rank higher in priority than the bitwise operators for integers found in Section 5.5.4.



Table 5.3. Numeric Type Arithmetic Operators

Arithmetic Operator

Function

expr1 ** expr2

expr1 raised to the power of expr2[a]

+expr

(unary) expr sign unchanged

-expr

(unary) negation of expr

expr1 ** expr2

expr1 raised to the power of expr2[a]

expr1 * expr2

expr1 times expr2

expr1 / expr2

expr1 divided by expr2 (classic or true division)

expr1 // expr2

expr1 divided by expr2 (floor division [only])

expr1 % expr2

expr1 modulo expr2

expr1 + expr2

expr1 plus expr2

expr1 - expr2

expr1 minus expr2


[a] ** binds tighter than unary operators to its left and looser than unary operators to its right.


Here are a few more examples of Python's numeric operators:


>>> -442 - 77
-519
>>>
>>> 4 ** 3
64
>>>
>>> 4.2 ** 3.2
98.7183139527
>>> 8 / 3
2
>>> 8.0 / 3.0
2.66666666667
>>> 8 % 3
2
>>> (60. - 32.) * ( 5. / 9. )
15.5555555556
>>> 14 * 0x04
56
>>> 0170 / 4

30
>>> 0x80 + 0777
639
>>> 45L * 22L
990L
>>> 16399L + 0xA94E8L
709879L
>>> -2147483648L - 52147483648L
-54294967296L
>>> 64.375+1j + 4.23-8.5j
(68.605-7.5j)
>>> 0+1j ** 2 # same as 0+(lj**2)
(-1+0j)
>>> 1+1j ** 2 # same as 1+(lj**2)
0j
>>> (1+1j) ** 2
2j


Note how the exponentiation operator is still higher in priority than the binding addition operator that delimits the real and imaginary components of a complex number. Regarding the last example above, we grouped the components of the complex number together to obtain the desired result.





5.5.4. *Bit Operators (Integer-Only)


Python integers may be manipulated bitwise and the standard bit operations are supported: inversion, bitwise AND, OR, and exclusive OR (aka XOR), and left and right shifting. Here are some facts regarding the bit operators:


  • Negative numbers are treated as their 2's complement value.

  • Left and right shifts of N bits are equivalent to multiplication and division by (2 ** N) without overflow checking.

  • For longs, the bit operators use a "modified" form of 2's complement, acting as if the sign bit were extended infinitely to the left.


The bit inversion operator ( ~ ) has the same precedence as the arithmetic unary operators, the highest of all bit operators. The bit shift operators ( << and >> ) come next, having a precedence one level below that of the standard plus and minus operators, and finally we have the bitwise AND, XOR, and OR operators (&, ^, | ), respectively. All of the bitwise operators are presented in the order of descending priority in Table 5.4.



Table 5.4. Integer Type Bitwise Operators

Bitwise Operator

Function

~num

(unary) invert the bits of num, yielding -(num + 1)

num1 << num2

num1 left shifted by num2 bits

num1 >> num2

num1 right shifted by num2 bits

num1 & num2

num1 bitwise AND with num2

num1 ^ num2

num1 bitwise XOR (exclusive OR) with num2

num1 | num2

num1 bitwise OR with num2



Here we present some examples using the bit operators using 30 (011110), 45 (101101), and 60 (111100):


>>> 30 & 45
12
>>> 30 | 45
63
>>> 45 & 60
44
>>> 45 | 60
61
>>> ~30
-31
>>> ~45
-46
>>> 45 << 1
90
>>> 60 >> 2
15
>>> 30 ^ 45
51













5.6 Using DISTINCT to Eliminate Duplicates











 < Day Day Up > 





5.6 Using DISTINCT to Eliminate Duplicates



If a query returns a result that contains duplicate rows, you can remove duplicates and produce a result set in which every row is unique. To do this, include the keyword DISTINCT after SELECT and before the output column list.



Suppose that a query returns a result set that contains duplicated rows:










mysql> SELECT last_name FROM t;

+-----------+

| last_name |

+-----------+

| Brown |

| Larsson |

| Brown |

| Larsson |

+-----------+




Adding DISTINCT removes the duplicates and returns only unique rows:










mysql> SELECT DISTINCT last_name FROM t;

+-----------+

| last_name |

+-----------+

| Brown |

| Larsson |

+-----------+




Duplicate elimination for string values happens differently for binary and nonbinary strings. The strings 'ABC', 'Abc', and 'abc' are considered distinct if they're binary strings, but the same if they are nonbinary. (Stated another way, strings that vary only in lettercase are considered the same unless they're binary.)



Distinctiveness of rows is assessed taking NULL values into account. Suppose that a table t contains the following rows:










mysql> SELECT i, j FROM t;

+------+------+

| i | j |

+------+------+

| 1 | 2 |

| 1 | NULL |

| 1 | NULL |

+------+------+




For purposes of DISTINCT, the NULL values in the second column are considered the same, so the second and third rows are identical. Adding DISTINCT to the query eliminates one of them as a duplicate:










mysql> SELECT DISTINCT i, j FROM t;

+------+------+

| i | j |

+------+------+

| 1 | 2 |

| 1 | NULL |

+------+------+




Using DISTINCT is equivalent to using GROUP BY on all selected columns with no aggregate function. For such a query, GROUP BY just produces a list of distinct grouping values. If you display and group by a single column, the query produces the distinct values in that column. If you display and group by multiple columns, the query produces the distinct combinations of values in the column. For example, the following two queries are equivalent:










SELECT DISTINCT id FROM t;

SELECT id FROM t GROUP BY id;




As are these:










SELECT DISTINCT id, name FROM t;

SELECT id, name FROM t GROUP BY id, name;




Another correspondence between the behavior of DISTINCT and GROUP BY is that for purposes of assessing distinctness, DISTINCT considers all NULL values the same. This is analogous to the way that GROUP BY groups together NULL values.



A difference between DISTINCT and GROUP BY is that DISTINCT doesn't cause row sorting the way that GROUP BY does.



DISTINCT can be used with the COUNT() function to count how many distinct values a column contains. However, in this case, NULL values are ignored:










mysql> SELECT j FROM t;

+------+

| j |

+------+

| 2 |

| NULL |

| NULL |

+------+

mysql> SELECT COUNT(DISTINCT j) FROM t;

+-------------------+

| COUNT(DISTINCT j) |

+-------------------+

| 1 |

+-------------------+




COUNT(DISTINCT) is discussed further in section 5.5, "Aggregate Functions, GROUP BY, and HAVING."













     < Day Day Up > 



    Section 4.2.&nbsp; Tour of the Code










    4.2. Tour of the Code


    Since the template did all the work of creating the code, you don't really know what it's doing. In this section, we walk through the generated code and point out the interesting bits. In fact, all the generated code is included hereit's pretty small.



    4.2.1. Application


    The RCP SDK target you are using contains only framework libraries; you can't even run them. It's like having a JRE installedlots of great code, but it still needs to be told what to do. In regular Java systems, this is done by writing a class that has a main() method. In Eclipse, you write an application. An application is the entry point to a program or product. The application is run when the Runtime starts up, and when the application exits, Eclipse shuts down.


    The PDE wizard used the Hello RCP template to generate the org.eclipsercp.hyperbola.Application application below. Applications must implement IPlatformRunnable and thus a run() method. Think of this as your main() method.


    org.eclipsercp.hyperbola/Application
    public class Application implements IPlatformRunnable {
    public Object run(Object args) throws Exception {
    Display display = PlatformUI.createDisplay();
    try {
    int returnCode = PlatformUI.createAndRunWorkbench(
    display, new ApplicationWorkbenchAdvisor());
    if (returnCode == PlatformUI.RETURN_RESTART) {
    return IPlatformRunnable.EXIT_RESTART;
    return IPlatformRunnable.EXIT_OK;
    } finally {
    display.dispose();
    }
    }
    }


    The critical code is marked in bold. The application creates a Display and then starts an Eclipse Workbench by calling PlatformUI.createAnd RunWorkbench(Display, WorkbenchWindowAdvisor). This opens a window and simply loops forever, handling user-generated events such as mouse clicks, key presses, and mouse moves. The event loop finally returns when the last window is closed or when it is explicitly told to exit. Before returning from the application, the created Display must be disposed to free any allocated system resources.


    Note



    You can do just about anything you want in your application. In our example, we start up a UI, but you could just as well start a server of some sort. In other words, the Eclipse RCP can also be used for non-graphical applications.




    The application class must be linked into the Eclipse Runtime's applications extension point, as shown in Figure 4-7, thus making the Runtime aware of the application. Just as many Java JARs on a classpath may contribute classes that have a main() method, many Eclipse plug-ins in a system may contribute application extensions. In fact, one plug-in can contribute many applications. When Eclipse is started, one and only one application is identified as the application to run. Again, this is directly analogous to standard Java, where you specify exactly one class to run on the command line. More on this in the section on running and debugging.




    4.2.2. WorkbenchAdvisor


    In the application code shown above, we glossed over the Application WorkbenchAdvisor that was instantiated and passed into PlatformUI.createAndRunWorkbench(). In fact, this is the most important part of the story.


    As the name implies, a WorkbenchAdvisor tells the Workbench how to behavehow to draw, what to draw, etc. In particular, our Application WorkbenchAdvisor identifies two things:


    • The initial perspective to be shown.

    • The WorkbenchWindowAdvisor to be used.


    org.eclipsercp.hyperbola/ApplicationWorkbenchAdvisor
    public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
    private static final String PERSPECTIVE_ID =
    "org.eclipsercp.hyperbola.perspective";

    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
    IWorkbenchWindowConfigurer configurer) {
    return new ApplicationWorkbenchWindowAdvisor(configurer);
    }
    public String getInitialWindowPerspectiveId() {
    return PERSPECTIVE_ID;
    }
    }




    4.2.3. Perspective


    The initial perspective is identified by its extension identifier, as shown at the top right of Figure 4-7. The extension gives the perspective a human-readable name and specifies a class that defines the layout of the perspective. The given class must implement the IPerspectiveFactory interface and the createInitial Layout(IPageLayout) method. The org.eclipsercp.hyperbola.Perspective perspective is a trivial implementation that simply does nothing. This perspective is added in later chapters.


    org.eclipsercp.hyperbola/Perspective
    public class Perspective implements IPerspectiveFactory {
    public void createInitialLayout(IPageLayout layout) {
    }
    }


    Note



    As with applications, there may be many perspectives in the system. The application's WorkbenchAdvisor identifies only one of these as the initial perspective. While WorkbenchAdvisors must define an initial perspective, that setting can be overridden using preferences. This is detailed in Chapter 16, "Perspectives, Views, and Editors."






    4.2.4. WorkbenchWindowAdvisor


    Every window in your application has a WorkbenchWindowAdvisor that guides the UI in rendering the window. Window advisors are consulted at various points in the lifecycle of a window (e.g., preWindowOpen() and postWindowCreate()) and have the opportunity to control the creation of the window's contents. You will visit Hyperbola's window advisor often as you update the look and feel of the application.


    The ApplicationWorkbenchWindowAdvisor customizes Hyperbola windows. In the preWindowOpen() method, it sets the initial size and title of the window and hides the status line and toolbar. While we are looking at preWindowOpen(), go ahead and change the initial size of the window to make it a bit smaller than the default. Don't forget to save the file when you are done.


    org.eclipsercp.hyperbola/ApplicationWorkbenchWindowAdvisor
    public class ApplicationWorkbenchWindowAdvisor extends
    WorkbenchWindowAdvisor {

    public ApplicationWorkbenchWindowAdvisor(
    IWorkbenchWindowConfigurer configurer) {
    super(configurer);
    }

    public ActionBarAdvisor createActionBarAdvisor(
    IActionBarConfigurer configurer) {
    return new ApplicationActionBarAdvisor(configurer);
    }

    public void preWindowOpen() {
    IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
    configurer.setInitialSize(new Point(250, 350));
    configurer.setShowCoolBar(false);
    configurer.setShowStatusLine(false);
    configurer.setTitle("Hyperbola");
    }
    }




    4.2.5. ActionBarAdvisor


    ActionBarAdvisors create the actions needed for a window and position them in the window. They are instantiated using createActionBarAdvisor() on WorkbenchWindowAdvisor. Since we are just starting out and have no actions, the ActionBarAdvisor is largely empty.


    org.eclipsercp.hyperbola/ApplicationActionBarAdvisor
    public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
    super(configurer);
    }

    protected void makeActions(IWorkbenchWindow window) {
    }
    protected void fillMenuBar(IMenuManager menuBar) {
    }
    }


    Note



    The name ActionBarAdvisor does not do justice to this class. It actually controls what appears in the menu bar, the cool bar, also known as the toolbar, and the status line. As such, it is a focal point of customization in RCP applications.






    4.2.6. Summary


    That's it. You have seen all the code involved in creating the simple Hyperbola RCP application. Just to be sure you got all the steps right, use the Samples Manager detailed in Chapter 3, "Tutorial Introduction," to compare your workspace to the sample code for this chapterthey should be identical (except for possible formatting differences).


    Of course the application does not do much; it doesn't even have any actionsnor does it have any branding or splash screens. Nonetheless, the example shows how the major parts of the Eclipse RCP fit together.













    Chapter 8. System











     < Day Day Up > 







    Chapter 8. System





    For the myth is the foundation of life; it is the timeless schema, the pious formula into which life flows when it reproduces its traits out of the unconscious.

    �Thomas Mann



    The Java platform�the Java Virtual Machine plus the libraries�contains a tremendous amount of functionality that J2EE relies on as part of its implementation. For example, the hot deployment capability of servlet engines and EJB containers is due entirely to the ClassLoader architecture of the underlying JVM; without it, bouncing the server would be a necessity to load new versions of the code. Java Object Serialization is used implicitly in a number of places throughout the JDK and so becomes a cornerstone of J2EE. And, of course, in order to allow the container to walk and chew gum at the same time (figuratively), J2EE makes heavy use of the Java threading model to provide concurrent execution of incoming client requests.



    As a result, understanding key parts of the Java platform is an absolute "must" for any Java developer who wants to do serious work in the J2EE platform.















       < Day Day Up > 



      8.2 Formatting and Parsing Dates and Times








       

       










      8.2 Formatting and Parsing Dates and Times



      Like numbers, dates are formatted differently for different locales; for example, the date May 9, 2002 is formatted (in short form) as 5/9/02 for the U.S. English (en-US) locale and as 09/05/02 for the France French (fr-FR) locale. JSTL provides two actions, <fmt:formatDate> and <fmt:parseDate>, that format and parse dates, respectively.



      The <fmt:formatDate> action formats an instance of java.util.Date and outputs a string representation of that date. The three most common ways to create a date for <fmt:formatDate> are with <jsp:useBean>, <fmt_rt:formatDate>, or <fmt:parseDate>; for example, you can create a date with <jsp:useBean> like this:





      <fmt:setLocale value='en-US'/>

      <jsp:useBean id='today' class='java.util.Date'/>

      <fmt:formatDate value='${today}'/>



      In the preceding code fragment, the <jsp:useBean> action stores an instance of java.util.Date (which represents the current date) in a scoped variable named today in page scope. Subsequently, the <fmt:formatDate> action accesses that scoped variable and formats it according to the U.S. English locale. If the current date is the 9th of May in the year 2002, the output of the preceding code fragment will be May 9, 2002. If you change the locale specified with the <fmt:setLocale> action in the preceding code fragment to fr-FR, the output of the preceding code fragment will be 9 mai 2002.



      You can also use the <fmt_rt:formatNumber> action to format an instance of java.util.Date that's created with a JSP expression, like this:





      <fmt:setLocale value='en-US'/>

      <fmt_rt:formatDate value='<%= new java.util.Date() %>'/>



      The preceding code fragment is functionally identical to the code fragment listed above that uses the <jsp:useBean> action.



      The <fmt:parseDate> action parses a string into an instance of java.util.Date, so you can use <fmt:parseDate> in concert with <fmt:formatDate> to format a string representation of a date, like this:





      <fmt:setLocale value='en-US'/>

      <fmt:parseDate value='May 9, 2002' var='date'/>

      <fmt:formatDate value='${date}' dateStyle='short'/>



      In the preceding code fragment, <fmt:parseDate> parses the string May 9, 2002 and stores the resulting java.util.Date instance in a scoped variable named date in page scope. Subsequently, the <fmt:formatDate> action accesses that scoped variable and formats the date with the short date style as 5/9/02.



      The <fmt:formatDate> and <fmt:parseDate> actions can format and parse, respectively, a date, a time, or both. By default, those actions format and parse a date, but you can specify just the time or both the date and the time with the <fmt:formatDate> and <fmt:parseDate> type attributes; for example, you can format both the date and time like this:





      <fmt:setLocale value='en-US'/>

      <jsp:useBean id='today' class='java.util.Date'/>

      <fmt:formatDate value='${today}' type='both'/>



      Assuming a current date and time of May 9, 2002 at 2:36:53 P.M., the preceding code produces the following output for the U.S. English locale: May 9, 2002 2:36:53 PM. If you set the <fmt:formatDate> type attribute to time, the preceding code fragment will produce this output for the U.S. English locale: 2:36:53 PM.



      Dates and times can be formatted (and parsed) with predefined formats, which are specified with the <fmt:formatDate> (and <fmt:parseDate>) dateStyle and timeStyle attributes. Valid values for those attributes are default, short, medium, long, and full, where default is the same as medium. The default value is used if the dateStyle and timeStyle attributes are not specified.



      Examples of those predefined formats are shown in Table 8.4.































































      Table 8.4. Predefined Date and Time Formats


      Value





      Description





      Example Date and Time for U.S. Locale





      short





      Numeric





      10/19/00 6:07 PM





      medium





      Longer than short





      Oct 19, 2000 6:07:01 PM





      long





      Longer than medium





      October 19, 2000 6:07:01 PM MDT





      full





      Completely specified





      Thursday, October 19, 2000 6:07:01 PM MDT





      It's also easy to format dates and times for non-Latin languages; for example, here's how you'd format the current date and time for Chinese, Arabic, and Thai, all in the same JSP page:





      <%-- Use UTF-8 to display multiple languages --%>

      <%@ page contentType='text/html; charset=UTF-8' %>

      <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt' %>



      <%-- Chinese, Taiwan --%>

      <fmt:setLocale value='zh-TW'/>

      <fmt_rt:formatDate value='<%= new java.util.Date() %>'

      type='both'

      dateStyle='full'

      timeStyle='full'/>

      <p>



      <%-- Arabic, Saudi Arabia --%>

      <fmt:setLocale value='ar-SA'/>

      <fmt_rt:formatDate value='<%= new java.util.Date() %>'

      type='both'

      dateStyle='full'

      timeStyle='full'/>

      </p><p>



      <%-- Thai, Thailand --%>

      <fmt:setLocale value='th-TH'/>

      <fmt_rt:formatDate value='<%= new java.util.Date() %>'

      type='both'

      dateStyle='full'

      timeStyle='full'/>

      </p>



      Here's what the preceding code fragment produces for the 25th of May, 2002 at 2:17:17 PM, EDT:





      If the predefined formats listed in Table 8.4 are not sufficient, you can specify custom formatting patterns for both the <fmt:formatDate> and <fmt:parseDate> actions. Those custom formatting patterns are discussed in "Custom Patterns for Dates and Times" on page 336.



      You can also specify a time zone for <fmt:formatDate> and <fmt:parseDate> with the timeZone attribute. That attribute comes in handy when a Web server resides in one time zone and clients reside in another; for example, the following code fragment formats the current date and time for the America/Denver time zone:





      <fmt:setLocale value='en-US'/>

      <jsp:useBean id='today' class='java.util.Date'/>

      <fmt:formatDate value='${today}'

      type='both'

      timeZone='America/Denver'

      timeStyle='full'/>



      In the preceding code fragment, the timeStyle attribute for the <fmt:formatDate> action is specified as full, so the time zone will be displayed. If the current date and time is May 9, 2002 at 3:16:13 PM, the output of the preceding code fragment will be:





      May 9, 2002 3:16:13 PM MDT



      In addition to the <fmt:formatDate> and <fmt:parseDate> timeZone attributes, you can also specify time zones with the <fmt:timeZone> and <fmt:setTimeZone> actions, which are discussed in "Using Time Zones" on page 343.



      Custom Patterns for Dates and Times



      If the predefined date and time patterns�see Table 8.4�are not sufficient for your needs, you can specify custom date and time patterns; for example, the following code fragment formats the current date and time according to a custom pattern:





      <jsp:useBean id='now' class='java.util.Date'/>



      <fmt:formatDate value='${now}'

      type='both'

      pattern="MM/dd/yyyy' at: 'hh:mm:ss"/>



      The preceding code fragment formats the current date and time using the pattern MM/dd/yyyy' at: 'hh:mm:ss. Assuming a current date and time of May 11, 2002 at 10:43:53, the preceding code fragment will produce the following output: 05/11/2002 at: 10:40:53. All characters within a custom date pattern are interpreted by the <fmt:formatDate> and <fmt:parseDate> actions, except for characters enclosed in single quotes. In the preceding code fragment, the quoted string ' at: ' is not interpreted.



      You can also use custom date patterns to parse a string representation of a date with <fmt:parseDate>, like this:





      <fmt:parseDate value='6/20/1957'

      var='parsedDate'

      pattern='MM/dd/yyyy'/>



      <fmt:formatDate value='${parsedDate}'

      pattern="MMMM dd'th, 'yyyy' was a 'EEEE"/>



      In the preceding code fragment, <fmt:parseDate> parses the string 6/20/1957 using the pattern MM/dd/yyyy and stores the resulting instance of java.util.Date in a scoped variable named parsedDate. Subsequently, <fmt:formatDate> formats that date with another custom date pattern. The output of the preceding code fragment is June 20th, 1957 was a Thursday.



      You should note that patterns specified for <fmt:parseDate> must match the string that <fmt:parseDate> parses; for example, consider the following code fragment:





      <fmt:parseDate value='20/6/1957'

      pattern='MM/dd/yyyy'/>



      In the preceding code fragment, <fmt:parseDate> will throw an exception because 20 is not a valid numeric value for a month, even though the pattern MM/dd/yyyy is valid for many locales.



      Table 8.5 lists the characters you can use in a custom date pattern.





























































































































































































































































      Table 8.5. Characters Used in Date and Time Patterns[a]


      Letter





      Date or Time Component





      Presentation





      Examples





      G





      Era designator





      Text





      AD





      y





      Year





      Year





      2002 02





      M





      Month in year





      Month





      August Aug 08





      w





      Week in year





      Number





      50





      W





      Week in month





      Number





      3





      D





      Day in year





      Number





      224





      d





      Day in month





      Number





      20





      F





      Day of week in month





      Number





      6





      E





      Day in week





      Text





      Wednesday Wed





      a





      Am/pm marker





      Text





      AM PM





      H





      Hour in day (0-23)





      Number





      0





      k





      Hour in day (1-24)





      Number





      24





      K





      Hour in am/pm (0-11)





      Number





      0





      h





      Hour in am/pm (1-12)





      Number





      12





      m





      Minute in hour





      Number





      50





      s





      Second in minute





      Number





      55





      S





      Millisecond





      Number





      960





      z





      Time zone





      General time zone





      Pacific Standard Time PST GMT-08:00





      Z





      Time zone





      RFC 822 time zone





      0800





      [a] This table and the related discussion that follows is derived from the Java documentation for the java.text.SimpleDateFormat class.





      The letters listed in the preceding table are usually specified in multiples; the number of times a letter is repeated determines presentation as follows, where each heading (such as Text, Number, etc.) corresponds to the Presentation column from the preceding table:[10]



      [10] All of the following examples assume an en-US locale.





      • Text:



        • Formatting:

          If you specify 4 or more letters, a full format is used; otherwise, an abbreviated form is used if available. For example, for Sunday, the patterns E, EE, and EEE will display Sun, whereas the pattern EEEE will display Sunday.





        • Parsing:

          Both the full and abbreviated forms are accepted, independently of the number of pattern letters.







      • Number:



        • Formatting:

          No matter how many letters you specify, the minimum number of digits is always shown; for example, if the day of the year is 125, that value will be displayed for D, DD, and DDD. If you specify more letters than the minimum number of digits, the number is zero-padded; for example, if the day of the year is 125 and you specify DDDD, then 0125 will be displayed.





        • Parsing:

          The number of letters is ignored unless it's needed to separate adjacent fields.







      • Month:



        • Formatting:

          If the number of letters is less than 3, the month is interpreted as a Number; otherwise, it's interpreted as Text. For example, for the month of May, M and MM will display 5 and 05, respectively, whereas MMM will display May.





        • Parsing:

          Same as formatting.







      • Year:



        • Formatting:

          If the number of letters is less than 4, the year is truncated to two digits; for example, for the year 2002, y, yy, and yyy will all display 02, whereas yyyy will display 2002.





        • Parsing:

          If the number of letters is more than 2, the year is interpreted literally; for example, for the pattern MM/dd/yyyy, the string 01/11/12 will be parsed as January 11, 12 AD. For an abbreviated year pattern�y or yy�the year is interpreted relative to the time span into which it falls. A 100-year time span is split into two parts arranged around the current date as follows: one part spans the past 80 years, and the other spans the next 20 years. Given an abbreviated year, the time span into which the year falls is determined, and the century information is taken from that time span. For example, for a parsing action used on January 1, 1997, the string 01/11/12 would be parsed as January 11, 2012, because 2012 falls into the time span 1997 + 20 years and 1912 does not fall into the time span 1997 - 80 years; and the string "05/04/64" would be parsed as May 4, 1964 because 1964 falls into the time span 1997 - 80 years and 2064 does not fall into the time span 1997 + 20 years.







      • General time zone:



        • Formatting:

          Time zones specified with a name, such as America/Denver, are interpreted as Text. You can also specify a time zone as a GMT offset, such as GMT-02:00 or GMT+03:30.





        • Parsing:

          Same as formatting, except RFC 822 time zones are also accepted.







      • RFC 822 time zone:[11]

        [11] See http://www.ietf.org/rfc/rfc0822.txt?number=822 for more information about RFC 822.





        • Formatting:

          A 4-digit time zone format, such as 0700.





        • Parsing:

          Same as formatting, except general time zones are also accepted.









      Table 8.6 lists some example date and time patterns for the U.S. English locale.













































































      Table 8.6. Date and Time Pattern Examples for U.S. English


      Pattern





      Result





      MM/dd/yyyy





      05/06/2002





      h 'o''clock and' mm 'minutes'





      2 o'clock and 36 minutes





      'Today is: 'EEEE, MMM dd





      Today is Monday, May 06





      h:mm a, z





      2:36 AM, MST





      E, MMM d'th at precisely:' hh:mm:ss:





      Mon, May 6th at precisely: 02:36:27:497





      'It''s' yyyy G





      It's 2002 AD





      k:m:s, dd/MM ''yy Z





      14:36:27, 06/05 '02 -0600





      The example patterns in the preceding table use a wide range of the characters listed in Table 8.5, including the characters for time zones and milliseconds. Notice that two consecutive single quotes in a row produce one single quote in the output.



      Figure 8-5 shows a JSP page that you can use to specify a locale and a custom date pattern to format the current date. The top picture in Figure 8-5 shows a pattern that generates a fairly complete date format, and the bottom picture shows a pattern that generates a short date format with the year fully specified.



      Figure 8-5. Formatting Dates with Custom Patterns





      The JSP page shown in Figure 8-5 is listed in Listing 8.4.



      The preceding JSP page lets you select a locale from any of the available locales that the JDK uses to format dates, by calling java.text.DateFormat.getAvailableLocales(). Because you can select from so many different locales, the preceding JSP page uses the UTF-8 charset. See "Unicode and Charsets" on page 260 for more information about that charset.



      After setting the charset, the preceding JSP page creates a scoped variable for the previously selected locale. If no locale was selected, the JSP page sets that scoped variable to the default locale. The JSP page uses that scoped variable to set the locale with <fmt:setLocale> and also to select the previously selected locale for the HTML select element that displays available locales for date formatting. Subsequently, the JSP page creates a scoped variable named now with <jsp:useBean> and uses <fmt:formatDate> to format that date with the specified pattern. The rest of the JSP page creates the form.





      Listing 8.4 Formatting Dates with Custom Patterns




      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

      <html>

      <head>

      <title>Formatting Dates With Patterns</title>

      </head>



      <body>

      <%@ page contentType='text/html; charset=UTF-8' %>



      <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %>

      <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt'%>

      <%@ taglib uri='http://java.sun.com/jstl/core_rt'

      prefix='c_rt' %>



      <%-- Create a scoped variable based on the locale

      request parameter --%>

      <c:choose>

      <c:when test='${empty param.locale}'>

      <c_rt:set var='locale'

      value='<%= java.util.Locale.getDefault() %>'/>

      </c:when>

      <c:otherwise>

      <c:set var='locale' value='${param.locale}'/>

      </c:otherwise>

      </c:choose>



      <%-- Set the locale according to the locale request

      parameter --%>

      <fmt:setLocale value='${locale}'/>



      <%-- Create a scoped variable that contains the current

      date --%>

      <jsp:useBean id='now' class='java.util.Date'/>



      <%-- Show formatted number --%>

      <font size='5'>Formatted date:

      <c:choose>

      <c:when test='${not empty param.pattern}'>

      <fmt:formatDate value='${now}'

      pattern='${param.pattern}'/>

      </c:when>

      <c:otherwise>

      <fmt:formatDate value='${now}'/>

      </c:otherwise>

      </c:choose>

      </font>



      <%-- Because this form does not specify an action, this

      JSP page will be reloaded when the submit button

      is activated --%>

      <form>

      <table>

      <tr>

      <td>Format this date:</td>

      <td><c:out value='${now}'/></td>

      </tr>



      <tr>

      <td>With this locale:</td>

      <td>

      <select name='locale'>

      <c_rt:forEach var='thisLocale'

      items='<%= java.text.DateFormat.

      getAvailableLocales()%>'>

      <option

      <c:if test='${locale == thisLocale}'>

      selected

      </c:if>



      <c:out value='>${thisLocale}'

      escapeXml='false'/>

      </option>

      </c_rt:forEach>

      </select>

      </td>

      </tr>



      <tr>

      <td>With this pattern:</td>

      <td><input type='text' name='pattern' size='50'

      value='<c:out value="${param.pattern}"/>'/>

      </td>

      </tr>

      </table>

      <p><input type='submit'/>

      </form>

      </body>

      </html>
















         

         


        Out of the Frozen North













        Out of the Frozen North

        In 1992, a guy in Finland named Linus Torvalds took a then-popular, small, educational version of UNIX called Minix, decided it wasn’t quite what he wanted, and proceeded to rewrite and extend it so that it was more to his taste. Lots of enthusiastic programmers have started projects like that, but to everyone’s astonishment, Linus actually finished his. By mid-1993, his system had long since left its Minix roots and was becoming a genuinely usable version of UNIX. Linus’s system was picked up with great enthusiasm by programmers, and later by users, all over the Internet. It spread like crazy, to become the fastest-growing part of UNIX-dom.


        Linux is popular for three reasons:




        • It works well, even on a small, cheap PC. A 386 PC with 4MB of random-access memory (RAM) and a 40MB hard drive can run Linux — barely. (You can find computers like that for $5 at the thrift store these days.) On a top-of-the-line Pentium PC, its performance approaches that of a full-blown traditional UNIX workstation.




        • Lots of enthusiastic people are working on Linux, with wonderful new features and additions available every day. Many of them even work.




        • It’s free!




        The many developers of Linux proudly describe it as a “hacker’s system,” one written by and for enthusiastic programmers. (This classic meaning of hacker should not be confused with the other, media-debased “computer vandal” definition.) These programmers keep up the development of Linux at a brisk pace, and a new “development” version is made available on the Internet every few days. Every once in a while, the developers decide that they have gotten enough bugs out of their recent developments, and they release a “stable” version, which stays constant for months rather than days. Most normal people use the stable version rather than a development version. Using a development version of Linux is sort of like living in a house inhabited by a large family of carpenters and architects: Every morning when you wake up, the house is a little different. Maybe you have a new turret, or some walls have moved. Or perhaps someone has temporarily removed the floor under your bed. (Oops — sorry about that.)


        Linux started life as the operating system of choice for students and other cheapskates . . . er . . . users who wanted a UNIX system of their own but couldn’t afford a traditional UNIX workstation. As Linux has matured into a stable, reliable UNIX system, this base has expanded to include companies and institutions that could afford traditional UNIX workstations, but found that Linux enabled them to add PC-based workstations at a fraction of the cost. In fact, Linux is now conservatively estimated to have more than 18 million users, making it the second or third most popular operating system in the world, behind Windows and about even with the Macintosh operating system.











        1.15 Summary

        Team-Fly
         

         

        TCP/IP Illustrated, Volume 2: The Implementation
        By
        Gary R. Wright, W. Richard Stevens
        Table of Contents
        Chapter 1. 
        Introduction


        1.15 Summary


        This chapter provided an overview of the Net/3 networking code. Using a simple program (Figure 1.2) that sends a UDP datagram to a daytime server and receives a reply, we've followed the resulting output and input through the kernel. Mbufs hold the information being output and the received IP datagrams. The next chapter examines mbufs in more detail.


        UDP output occurs when the process executes the sendto system call, while IP input is asynchronous. When an IP datagram is received by a device driver, the datagram is placed onto IP's input queue and a software interrupt is scheduled to cause the IP input function to execute. We reviewed the different interrupt levels used by the networking code within the kernel. Since many of the networking data structures are shared by different layers that can execute at different interrupt priorities, the code must be careful when accessing or modifying these shared structures. We'll encounter calls to the spl functions in almost every function that we look at.


        The chapter finishes with a look at the overall organization of the source code in Net/3, focusing on the code that this text examines.


        Exercises


        1.1

        Type in the example program (Figure 1.2) and run it on your system. If your system has a system call tracing capability, such as trace (SunOS 4.x), truss (SVR4), or ktrace (4.4BSD), use it to determine the system calls invoked by this example.

        1.2

        In our example that calls IF_DEQUEUE in Section 1.12, we noted that the call to splimp blocks network device drivers from interrupting. While Ethernet drivers execute at this level, what happens to SLIP drivers?





          Team-Fly
           

           
          Top
           


          15.4 Performing Transactions from Within Programs




          I l@ve RuBoard










          15.4 Performing Transactions from Within Programs




          15.4.1 Problem



          You're writing a
          program that needs to implement transactional operations.





          15.4.2 Solution



          Use the transaction abstraction provided by your language API, if it
          has such a thing. If it doesn't, use the
          API's usual query execution mechanism to issue the
          transactional SQL statements directly.





          15.4.3 Discussion



          When you run queries interactively from mysql (as
          in the examples shown in the previous section), you can see by
          inspection whether statements succeed or fail and determine on that
          basis whether to commit or roll back. From within a non-interactive
          SQL script stored in a file, that doesn't work so
          well. You cannot commit or roll back conditionally according to
          statement success or failure, because MySQL includes no
          IF/THEN/ELSE construct for controlling the flow of
          the script. (There is an IF( ) function, but
          that's not the same thing.) For this reason,
          it's most common to perform transactional processing
          from within a program, because you can use your API language to
          detect errors and take appropriate action. This section discusses
          some general background on how to do this. The next sections provide
          language-specific details for the Perl, PHP, Python, and Java APIs.



          Every API
          supports transactions, even if only in the sense that you can
          explicitly issue transaction-related SQL statements such as
          BEGIN and COMMIT. However, some
          APIs also provide a transaction abstraction that allows you to
          control transactional behavior without working directly with SQL.
          This approach hides the details and provides better portability to
          other databases that support transactions but for which the
          underlying SQL syntax may differ. The Perl, Python, and Java MySQL
          interfaces provide such an abstraction. PHP does not; you must issue
          the SQL statements yourself.



          The next few sections each implement the same example to illustrate
          how to perform program-based transactions. They use a table
          t that has the following initial contents that
          show how much money two people have:



          +------+------+
          | name | amt |
          +------+------+
          | Eve | 10 |
          | Ida | 0 |
          +------+------+


          The sample transaction is a simple financial transfer that uses two
          UPDATE statements to give six dollars of
          Eve's money to Ida:



          UPDATE money SET amt = amt - 6 WHERE name = 'Eve';
          UPDATE money SET amt = amt + 6 WHERE name = 'Ida';


          The result is a table that looks like this:



          +------+------+
          | name | amt |
          +------+------+
          | Eve | 4 |
          | Ida | 6 |
          +------+------+


          It's necessary to execute both statements within a
          transaction to ensure that both of them take effect at once. Without
          a transaction, Eve's money disappears without being
          credited to Ida if the second statement fails. By using a
          transaction, the table will be left unchanged if statement failure
          occurs.



          The example programs for each language are located in the
          transactions directory of the
          recipes distribution. If you compare them,
          you'll see that they all employ a similar framework
          for performing transactional processing:




          • The statements of the transaction are grouped within a control
            structure, along with a commit operation.


          • If the status of the control structure indicates that it did not
            execute successfully to completion, the transaction is rolled back.



          That logic can be expressed as follows, where
          block represents the control structure used to
          group statements:



          block:
          statement 1
          statement 2
          ...
          statement n
          commit
          if the block failed:
          roll back


          In Perl, the control structure is an
          eval block that succeeds or fails and returns an
          error code. Python and Java use a try block that
          executes to the end if the transaction was successful. If an error
          occurs, an exception is raised that triggers execution of a
          corresponding error-handling block to roll back the transaction. PHP
          does not have these constructs, but you can achieve the same effect
          by executing the statements of the transaction and a commit operation
          within a function. If the function fails, roll back.



          The benefit of structuring your code as just described is that it
          minimizes the number of tests needed to determine whether to roll
          back. The alternative�checking the result of each statement
          within the transaction and rolling back on individual statement
          errors�quickly turns your code into an unreadable mess.



          A subtle point to be aware of when
          rolling back within languages that raise exceptions is that it may be
          possible for the rollback itself to fail, causing another exception
          to be raised. If you don't want to deal with that,
          issue the rollback within another block that has an empty exception
          handler. The example programs for Perl, Python, and Java do this.




          Checking How API Transaction Abstractions Map onto SQL Statements



          For APIs that provide a
          transaction abstraction, you can see how the interface maps onto the
          underlying SQL by enabling logging in your MySQL server and then
          watching the query log to see what statements the API executes when
          you run a transactional program.











            I l@ve RuBoard