1 September 2020

Boss Statements vs. Worker Statements

There are two types of statemets in computer languages. Worker statements are simple executable statements. They constitute grammmatically complete imperative sentences.

Boss statements need a control a block of code. They are subordinating clauses and need a block of code to be complete. Computer languages only undersstand complete sentences.

We will look at these in Java and Python. You will see Java is much more "modest" than Python. In Python everything is public. It's a nudist camp.

In Java you dress like a Puritan.

Java

A block of code is lines of code enclosed in matching curly braces.

Python

A block of code is indented lines of code.

In both languages:

Making a Point class in Python

Here is our Java class.

public class Point
{
    //state or instance variable
    private int x;
    private int y;
    //signature: list of types in the argment list
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    //method name overloading. Two methods can have
    //the same name if their sigs are different.
    public Point()
    {
        this(0,0);
    }
    @Override
    public String toString()
    {
        return String.format("(%s, %s)", x, y);
    }
    @Override
    public boolean equals(Object o)
    {
        //the species test
        if( !(o instanceof Point))
        {
            return false;
        }
        Point that = (Point) o;
        return that.x == x && that.y == y;
    }
    public int getX()
    {
        return x;
    }
    public int getY()
    {
        return y;
    }
    public void setX(int x)
    {
        this.x = x;
    }
    public void setY(int y)
    {
        this.y = y;
    }
    public double distanceTo(Point that)
    {
        return Math.hypot(x - that.x, y - that.y);
    }
    public int taxiCabDistance(Point that)
    {
        return abs(x - that.x) + abs(y - that.y);
    }
    //poopsmith
    private int abs(int x)
    {
        // ternary operator:   P? ifTrue: ifFalse
        // predicate: boolean valued expression.
        // P is one of these
        return x < 0? -x : x;
    }
    public static void main(String[] args)
    {
        Point p = new Point(3,4);
        Point origin = new Point();
        Point q = new  Point(3,4);
        System.out.println(p);
        System.out.println(origin);
        System.out.println(origin.distanceTo(p));
        System.out.println(p.distanceTo(origin));
        System.out.println(origin.taxiCabDistance(p));
        System.out.println(p.taxiCabDistance(origin));
        System.out.println(p == q);
        System.out.println(p.equals(q));

    }
}

Here is our Python class.

import math   #you need to import the math library in Python.  You don't
#in Java.
class Point:    #boss statements end with a colon.
    # this special method runs right when a Point is created.
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    # this is a Python toString method.
    def __str__(self):
        return f"({self.x}, {self.y})"
    # This is Python's equals method.
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    #here are regular methods, done much as they are in Java
    def distance_to(self, other):
        return math.hypot(self.x - other.x, self.y - other.y)
    def taxicab_distance(self, other):
        return abs(self.x - other.x) + abs(self.y - other.y)
#This is the "main routine"
p = Point(3,4)
print(p)
q = Point()
print(q)
print(p.distance_to(q))
print(p.taxicab_distance(q))

Python has no separation of primitive and object types. Everything is an object.


unix> python Point.py 
(3, 4)
(0, 0)
5.0
7

Wrapper Classes

A wee bit of ugliness

jshell> ArrayList<int> al = new ArrayList<>();
|  Error:
|  unexpected type
|    required: reference
|    found:    int
|  ArrayList<int> al = new ArrayList<>();
|            ^-^

Ouch. Primitive types cannot be useed as type parameters in generic types such as ArrayList. Whaddya do if you actually want a list of intetgers?

Wrapper classes come a ridin' to the rescue!

jshell> ArrayList<Integer> al = new ArrayList<>();
al ==> []

jshell> al.add(56)
$2 ==> true

jshell> al.add(44)
$3 ==> true

jshell> al.add(15)
$4 ==> true

jshell> al
al ==> [56, 44, 15]

Wheeeee!!

Autoboxing This is when a primitive is automatically wrapped in a wrapper type. It entails a tacit call to new.

jshell> Integer q = 7;
q ==> 7

We learned today that the use of new Integer(7) is deprecated. The autoboxing way is the right way to do this. Java automatically "boxes" your primitive integer into an Integer object.

Autounboxing This is when a wrapper object silently regurgitates the primitive inside of it.

Here we use the "deprected way" to show you that what we have here is a gen-yoo-wine Integer. Then we unbox it.

jshell> Integer r = new Integer(5);
r ==> 5

jshell> int s = r;
s ==> 5

We know s is definitely primitive. Here is more evidence for doubting Thomases.

jshell> s.toString()
|  Error:
|  int cannot be dereferenced
|  s.toString()
|  ^--------^

Static Goodness The wrapper classes contain lots of useful static constants. Cling to them.

jshell> Integer.BYTES
$9 ==> 4

jshell> Integer.MAX_VALUE
$10 ==> 2147483647

jshell> Integer.MIN_VALUE
$11 ==> -2147483648

jshell> Integer.TYPE
$12 ==> int

There is a valueOf method that works like this.

jshell> Integer n = Integer.valueOf(7);
n ==> 7

But this is simpler and does the same dang thing.

jshell> n = 7;
n ==> 7

When we start programming GUIs, you will see that a lot of numeric data come in as strings. There's a remedy for that.

jshell> String num  = "32324";
num ==> "32324"

jshell> int number = Integer.parseInt(num);
number ==> 32324

jshell> number
number ==> 32324

Don't be sheepish; try this at home!

jshell> String crazy = "baaa";
crazy ==> "baaa"

jshell> number = Integer.parseInt(num, 16)
number ==> 205604

jshell> number
number ==> 205604

jshell> //this convertedd the string from base 16 to decimal

You can see our base motives revealed here...

jshell> Integer.toString(1000, 16)
$21 ==> "3e8"

jshell> Integer.toString(1000, 5);
$22 ==> "13000"

Observe the possible punishments. This is a run-time error called an exception.

jshell> Integer.parseInt("cows")
|  Exception java.lang.NumberFormatException: For input string: "cows"
|        at NumberFormatException.forInputString (NumberFormatException.java:68)
|        at Integer.parseInt (Integer.java:652)
|        at Integer.parseInt (Integer.java:770)
|        at (#23:1)

Every primitive type has a wrapper type. Here is a decoder ring. Many of the methods in Integer have analogs in the other wrapper types.

Java Primitives and their Wrapper Classes
byteByte
shortShort
intInteger
longLong
booleanBoolean
floatFloat
doubleDouble
charCharacter

Character This has some nice static methods that come in handy. Java characters are two bytes wide to accomodate Unicode.

jshell> Character.BYTES
$24 ==> 2

These look very useful

jshell> Character.digit('a', 16)
$25 ==> 10

jshell> Character.isDigit('6')
$26 ==> true

jshell> Character.isWhitespace('\n')
$27 ==> true

jshell> Character.isWhitespace('\t')
$28 ==> true

Both of these work; one's less typing

jshell> Character.toString('a')
$29 ==> "a"

jshell> "" + 'a'
$30 ==> "a"

If you concatenate any Java object or primitive to a string, it is automatically converted into a string and it's concatenated.

Double your pleasure.


jshell> Double.parseDouble("6.02e23")
$31 ==> 6.02E23

jshell> Double.toString(45.4)
$32 ==> "45.4"

jshell> "" + 45.4
$33 ==> "45.4"

Scope of Variables

The scope of a variable is its lifetime in a program. JavaScript and Python have global scopes. Java does not.

Consider this prgram.

:
/**************************************************
*   Author: Morrison
*   Date created: 1 Sep 2020
*   Date last modified: 1 Sep 2020
**************************************************/

public class BadBreath
{
    public BadBreath()
    {
    }
    
    public static void main(String[] args)
    {
        for(int k = 0; k < 5; k++)
        {
            int y = k*k;  //y is born here.
            System.out.printf("The square of %s is %s.\n", k, y);

        }  //y died right at this curly brace.
        System.out.println(y);
    }
}

We now compile.

unix> javac BadBreath.java
BadBreath.java:20: error: cannot find symbol
        System.out.println(y);
                           ^
  symbol:   variable y
  location: class BadBreath
1 error
unix> 

Java has block scope. Here is how to determine the scope of a variable.

  1. A variable is not visible until it is created. There is no JS hoisting nonsense.
  2. A variable's block is delimited by the closest set of enclosing curly braces. A variable's scope ends when its block ends.
  3. Variables created in for loop's initalizer are out of scope once the loop's block ends.

Let's create the same program in Python.

for k in range(5):
    y = k*k
    print(f"The square of {k} is {y}.")

print(y)
##python has function scope.

Python has function scope. Variables die when the function containing them does.