## While Loops—Python

Sometimes we need to repeat code in our programs for a certain number of executions. Let’s consider the classic triangle problem:

```=
==
===
====
=====
======
=======
========
=========
==========
```

This is a typical problem that computer science students use to learn about loops. In this problem, we have to print a triangle to the console where the size is specified by the user. Since we don’t know the size of the triangle ahead of time, we won’t be able to do something like this:

```print('=')
print('==')
print('===')
# continued...
```

Our issue is that right now, this code can only print a triangle that has a base size of three. If the user wants ten, we are out of luck. What we need is a programming construct that will continue to build the triangle until it hits the proper size.

Here is the example code of how to do this

```size = int(input('Enter the size of the triangle => '))
counter = 0

while counter < size:  # counter < size is the terminating condition.
# The next two lines repeat as long as condition < size
print('=' * counter) # Print the triangle
counter += 1 # Important! Update the counter variable!
```

This code accomplishes what we want it to do. This is the output we get when we run this code.

```Enter the size of the triangle => 5

=
==
===
====```

Let’s talk about why this works. While loops begin with the `while` keyword followed by a condition. The loop will repeat code inside of the while block as long as the condition is true.

In our case, the condition is `counter < size` so as long as our counter is less than the size of the triangle that the user specified, our condition will be true and the loop will continue to repeat. As soon as `size >= counter` the loop will terminate and the program will return to it’s normal execution flow.

Inside of the triangle, we print our triangle and then update our counter variable by 1. It is critical that we update our counter variable because without it, the loop will run forever.

```while counter < size:
print('=' * counter)
print('Loop is over') # Note! We never get to this statement! How come?
```

The code above will run forever in what is called an 'infinate loop'. The reason this happens is that we fail to increment the counter variable. Remember that loops always run while the terminating condition is true. Since counter is always less than size, our condtion never becomes false and the loop runs forever.
Sometimes we make infinate loops on purpose

```while True:
print('Infinate loop')
```

Since we are passing the contant `True` to our loop here, our loop will run forever. It’s on the developer at this point to kill the loop, which will learn when we cover the `break` keyword.

Finally, Python let’s us add an else statement to while loops that will run once the loop is over.

```size = int(input('Enter the size of the triangle => '))
counter = 0

while counter < size:
print('=' * counter)
counter += 1
else:
print('triangle complete') # This code runs when the loop is over
```

## For Loops—Python

Python has a for loop which is allows us to step through each element in an iterable (generally anything that defines __iter__ or __getitem__ such as files, lists, tuples, etc.).

First let’s go through an example of a for loop

```for i in range(10):
print(str(i))
```

When run, this code produces the following output

```0
1
2
3
4
5
6
7
8
9
```

Let’s discuss how this works. Our loop begins with the keyword `for` followed by a variable or variables. After the variable, we have the `in` keyword followed by an iterable. The loop continues until there are no more items in the iterable.

In our example, the iterable is the `range` function. So when we have `range(10)` we are making a sequence of ten numbers 0-9. Everytime `range` produces a number, it gets assigned to the variable `i`. We then use `print(str(i))` to print the value of `i` to the console.

Here is another demonstration of the for loop, this time using a list

```names = ['Bob', 'Tina', 'Gene', 'Linda']

for name in names:
print(name)
```

Lists implement the correct protocals that allow them to be used in `for` loops. In this case, we populate a list with some names. Everytime the loop executes, the name variable is updated with the next name in the list. We then print the name to the console.

The `for` loop let’s us have more than one variable in the loop.

```names = [['Bob', 'Belcher'],
['Tina', 'Belcher'],
['Gene', 'Belcher'],
['Linda', 'Belcher']]

for fname, lname in names:
print(fname, ' ', lname)
```

Keep in mind that when you do this, your update variables need to match the number of variables in your sequence. So if we had three variables here, we would get an exception.

## Conditions—Python

Most of the time in programming, our programs execute one line at a time. So for example we might see something like this:

```name = input('Enter your name => ')  # This statement runs first
print('Hello ', name)  # Now this statement runs next
```

Sometimes our programs hit a fork in the road and they need to make a decision about the direction they are going to take. Python gives us conditional statements to help make such decision.

A conditional statement is a condition that changes the course of the program’s execution based on a true or false evaluation. Let’s start with a code example to help make this more clear.

```gender = 'F'
name = input('Enter your name => ')

if gender == 'F':
print('Hello Ms. ', name)   # This code only executes for women
# (gender == 'F')
else:
print ('Hello ', name)  # This code executes for anyone else
# (gender != 'F')
```

This code snippet demonstrates a conditional statement. We begin with a variable named `gender` that is set to the value ‘F’ for female. Ideally, if we know the gender of a person, we should offer the correct greeting for that person.

The `if gender == 'F':` is the conditional statement. What this statement is doing is using a true/false expression to decide if we should print ‘Hello Ms.’ instead of just the standard ‘Hello’ greeting. If our gender variable is ‘F’, we will print the ‘Hello Ms.’, otherwise we print the ‘Hello’ greeting.

We can handle multiple conditions with the `elif` keyword. Let’s build on our example:

```gender = 'F'
name = input('Enter your name => ')

if gender == 'F':               # First check if the gender is F
print('Hello Ms. ', name)   # This code only executes for women
# (gender == 'F')

elif gender == 'M':             # Now check if gender is M
print ('Hello Mr. ', name)  # This time print a greeting for men
# (gender == 'M')
else:
print ('Hello ', name)  # This code executes for anyone else
# (gender != 'F')
```

Adding the `elif` keyword is a way to stack up multiple conditions and define an action for each condition. Now I should point out at this time that `elif` and `else` are completely optional. So it is ok to do this:

```gender = 'F'
if gender == 'F':
print('Found female')
print ('Done checking for m/f') # At this point, the code continues
# executing normally
```

We can also check for false conditions by using the `!=` operator.

```gendar = 'F'
if gender != 'M':   # Execute the code inside of the if block if
# if the gender is not male
print('Found female')
```

## Bubble Sort—Java

The bubble sort is a very common algorithm that many computer science students are expected to learn. Yesterday I did a post that shows a Python implementation of the bubble sort which you can view here. Today I will demonstrate the same technique in Java.

```import java.util.Arrays;

public class BubbleSort {

public static void main(String [] args){
Integer [] nums = {9, 4, 2, 1, 10};
System.out.println("Unsorted is " + Arrays.toString(nums));

bubbleSort(nums);
System.out.println("Sorted is " + Arrays.toString(nums));
}

public static<T extends Comparable> void bubbleSort(T [] array){
int n = array.length;
T temp;

for(int i = 0; i < n; i++){
for (int j = 1; j  0){
//Swap the elements
temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
}
}
}
}
```

Java is a little more verbose than Python. Since it is a statically typed language (which means you have to declare the data type up front, as opposed to Python’s duck typing method), I chose to use generics to implement this sort.

Generics were introduced in JDK 1.5. They allow us to write code that is widely applicable to many types of objects without forcing us to use the Object class. You can find a wide use of generics in the java.util package.

In this case, I declared my generic method like this

```public static<T extends Comparable> void bubbleSort(T [] array){
```

Let’s go through this one word at a time.

1. public—This is the keyword that makes this method publically available
2. static—This keyword attaches this method to the class rather than an object
3. <T extends Comparable>—This is the code that declares this method to be a generic method. T is the type of the object, followed by `extends Comparable` which means that any object that implements the Comparable interface is accetable to this method.
4. T [] array—This declares an array of type T (which is any class that implements Comparable in this case)

Now that we have declared this to be a generic method, this method will work with any object that implements the Comparable interface. The Comparable interface is widely used throughout Java in sorting. It declares a `compareTo(T obj)` method which returns a positive number when an item is greater than the comparing object, zero when the two objects are equal, and a negative number when the comparing object is less than the other object.

Since this interface exists, Java lets us sort anything that implements this interface easily. That allows programmers a high degree of freedom and flexibility when creating custom classes because the programmer gets to decide how one object is greater than, less than, or equal to another object.

We apply the Comparable interface to this bubble sort method here

```if(array[j - 1].compareTo(array[j]) > 0){
//Swap the elements
temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
```

If the left hand portion `array[j - 1].compareTo(array[j])` is 0, then these two items are 0. If the result is a negative number then `array[j - 1]` is less than `array[j]`, otherwise `array[j - 1]` is greater than `array[j]` and it needs to get swapped.

When run, we get this output

```Unsorted is [9, 4, 2, 1, 10]
Sorted is [1, 2, 4, 9, 10]
```

## Bubble Sort—Python

Many computer science students are expected to perform sorting. Here is an example of doing a bubble sort in Python.

```def bubble_sort(array):
# Grab the length of the array
n = len(array)

# Iterate through array from 0 to n
for i in range(len(array)):

# Iterate through array from 1 to n - i
for j in range(1, n - i):

# Now check if the element at array[j - 1] is larger than array[j]
if array[j - 1] > array[j]:
# Perform a swap of the elements
temp = array[j - 1]
array[j - 1] = array[j]
array[j] = temp

if __name__ == '__main__':
unsorted = [10, 5, 2, 3, 1]
print('Unsorted list is: ', unsorted)

bubble_sort(unsorted)
print('Sorted list is now: ', unsorted)
```

## Introduction

Once upon a time, I was tutoring a student who had taken an introduction to Java course who had a unique course project. The student’s job was to build an implementation of Jeopardy throughout the course. At the beginning, they would start simple with a basic program that read user input from the console. At the end of the semester, they had a full fledged GUI program that communicated over network sockets, communicated with a database, and even had multi-threading.

I loved this project because it literally covered every possible programming topic outside of web programming. This student had to learn out how read and react to user input from both the GUI and the console. The requirements of the program required them how to learn to read from a file. There was plenty of opportunity to learn Object Orientated Programming (OOP). I was so impressed with the material that was covered with this project that I asked the student to share the assignments with me when the semester was over. Thankfully, the student agreed!

## Python Jeopardy

This is the beginning of a series of posts where we will recreate the Jeopardy program using the Python language. Our first task is to start by creating a plain text file that will contain our Jeopardy game board. Here is an excerpt of the file.

```Earthquakes::Jeoportmanteau!::Ashes to Ashes::Dust To Dust::"K" Mart
400::800::1200::1600::2000
Earthquakes::400::This well-known fault is considered the main boundary between the North American & Pacific plates::the San Andreas Fault
...
FJ::Last name of Sir Clifford, whose crippling war injuries make life difficult for his wife::Chatterley
```

The first line of the input file lists our categories in our game of Jeopardy. Since it’s common to use commas in Jeopardy questions, we use :: to seperate each of our categories. Our requirements state that we have to have five categories or the file is invalid.

The next line of the file lists all of the possible point values. Like the categories line, we use :: to seperate each point. There have to be five points and they must be whole numbers.

The next twenty-six lines contain the questions for the game of Jeopardy. We start with the question’s category, followed by it’s point value. After the points we have the question (or the answer, depending how you wish to view it). and then finally we have the question’s answer. Our requirements state that we have to have 25 questions.

However we have a special question that can appear anywhere in this file exception for the first two lines. This is the final Jeopardy question. This line starts with FJ and the program needs to respond correctly when it sees the final jeopardy question. An example of the final jeopardy line is found on the last line of our example.

## Implementation

Python supports object orientated programming, which lets us model components in the system as objects. At this point, we have two objects in our system. Our first kind of an object is our standard question. Let’s begin by making a class that models this component.

### GameTile

```class GameTile:
def __init__(self, category='', points=0, question='', answer=''):
self.category = category  # The question category
self.points = points  # The point value of this question
self.question = question  # The question

def __str__(self):  # This method creates a string representation of this object
# Let's store all of our properties in a dict object
result = {'category': self.category,
'points': self.points,
'question': self.question,

# Now we can convert the dict to a string which will give us friendly formatting
return str(result)

def __repr__(self):
# This method also creates a String representation of a Python object
# The Python debugger calls this method rather than __str__
# But we can just reuse our code by calling __str__
return self.__str__()
```

So this is our first Python class of this project. One thing users who are familiar with other languages such as Java may notice is that none of the properties of this class are encapsulated. This may seem odd but keep in mind that Python is about readability and conciseness. We certianly could use Python’s psuedo-private techniques and then add getters and setters, but doing so will simply bloat the code.

At this point, we don’t have a lot of behavior in this class. This class defines a constructor (__init__) and it overrides the __str__ and __repr__ methods to provide us with string representations of this object. In __str__, we store all of our properties in a Python dict variable and then use str() to convert it to a String. __repr__ just simply uses the code in __str__ so that we can get String representations in the console.

Here is the next class in our script that represents the Final Jeopardy question.

### FinalJeopardyTile

```class FinalJeopardyTile:
self.question = question

def __str__(self):
return str(result)

def __repr__(self):
return self.__str__()
```

Once again, we haven’t added much in terms of behavior in this class. That will come later. However both GameTile and FinalJeopardy serve a useful purpose in that we are grouping related information together into a single entity. Later on, we can add behavior to these classes to work on the data.

Now we have to process our game file and create these objects. Python is a lot like C++ in that we don’t have put our code exclusively in class. At this point in the project, reading the game file isn’t the job of any one particular class so we are going to define a module level function that does the job of reading the file and will return a dict of questions.

Here is enter readGameBoard function. Don’t get overwhelmed by the size of it because we are going to break it up into sections and explain each portion.

```# These are custom exceptions that we are going to use.
class InvalidGameFile(Exception):
pass

class IllegalCategoryCount(Exception):
pass

class IllegalPointsCount(Exception):
pass

# Read the entire file into memory

# Check that we have 28 lines in the game file
if len(rawLines) != 28:
# Throw our custom exception to indicate the file is invalid
raise InvalidGameFile

# Now this is going to store our files
fileLines = []
for line in rawLines:  # Iterate through rawLines one item at a time
# Now we need to remove any '\n' characters and store them in fileLines
fileLines.append(line.strip())

points = []  # Store the points to validate the file later
gameTiles = {}  # Store all of the questions here

# There has to be 5 unique categories
# We are going to split the first line apart by the :: character
categories = fileLines.split('::')

# Now check that we have 5 unique categories. We use the set() function that
# will remove any duplicates and then we are going to check the length. It has to be
# 5 per the requirements
if len(set(categories)) != 5:
raise IllegalCategoryCount  # Raise one of our custom exceptions

# There has to be 5 unique points
# So now we read the second line and split it one our :: character
pointValues = fileLines.split('::')

# Now, we have Strings in pointValues, but we need them to be integers
# So we iterate through pointValues and convert each item to an int
# before storing it in points. We use the int() function to do the conversion
for pv in pointValues:
points.append(int(pv))

# Now once again, we need to for 5 unique points so we use set again to remove
# the duplicates and then len to check the size
if len(set(points)) != 5:
raise IllegalPointsCount  # Throw a custom exception

for line in fileLines[2:]:  # Slice off the first two lines
#  Get a line and split it into its parts
parts = line.split('::')

#  Now we check that the category and points are valid
if parts in categories and int(parts) in points:
# We can create a GameTile object at this point
gameTile = GameTile(category=parts,
points=int(parts),
question=parts,

# If this our first insertion, we need to create a new list object to store our
# GameTiles in our dictionary
if parts not in gameTiles:
gameTiles[parts] = []
else:
# Otherwise we can add our gameTile to gameTiles. Notice that the category is the key
gameTiles[parts].append(gameTile)

# This handles the final jeopardy case
elif parts == 'FJ':
# gameTiles uses FJ as the key for Final Jeopardy and then we store a FinalJeopardyTile
else:
# Throw our custom exception
raise InvalidGameFile
return gameTiles  # Return our dictionary that contains our question and final Jeopardy
```

The first thing we do is open a file. Python makes it super easy to read an entire file into memory with just one line of code!

```
The open fucntion opens the file. It takes the path to the file (which is stored in gameFile and a flag that tells it kind of open operation we are performing. In this case 'r' means read. Then we just use the readlines() method to read the entire file into memory.

<h4>Check for the proper number of lines</h4>
Our file is only valid if it has 28 lines. Let's check that next.

if len(rawLines) != 28:
raise InvalidGameFile
```

Whenever you need to know the len of a string, list, tuple, etc, you can use the built-in len function. In our case, we are calling len on our rawLines variable. If the result is anything beside 28, our file is invalid and we will raise our custom InvalidGameFile exception.

#### Remove unwanted characters

Our next job is to remove any special characters such as newline '\n' from the game file. The way we do it is below

```fileLines = []
for line in rawLines:
fileLines.append(line.strip())
```

This code starts by creating an empty list object to store the modified file lines. Then we enter a for loop to go through each item in rawLines one item at a time. We use String's strip() function to remove unwanted characters and we then add it to fileLines.

#### Validate Categories

Our requirements expect us to have five unique categories. Here is the code that validates the categories.

```categories = fileLines.split('::')

if len(set(categories)) != 5:
raise IllegalCategoryCount
```

Python Strings have a split method that will split a string into parts based on a supplied character. In our case, we use the :: character to section off each part of our line. Doing so removes the :: characters in the line and it returns a collection of Strings. One item for each portion of our String.

Our next job is to make sure we have five unique categories. We already met the len() function above, but now we have the set() function. This function takes an iterable and removes all duplicates. By wrapping len() around a set() and checking for five, we can be sure that we only have 5 unique categories. Any more or less categories will cause us to raise our custom exception.

#### Validate Points

We also require that we have 5 unique values for points. We can do this very similar to categories with only a small change.

```points = []
pointValues = fileLines.split('::')

for pv in pointValues:
points.append(int(pv)) # Convert to integer here

if len(set(points)) != 5:
raise IllegalPointsCount
```

When we start by spliting our string, we end up with hopefully five strings. Python is a strongly typed language. If we want to make a number out of a String, we have use the appropriate function to do so. In our case, we use int() to convert a String to an integer (whole number) value.

If you attempt to call int() on a String that isn't a number, you will get an exception and your program will crash. This is a good thing because we can trace the program back to the point of failure and debug it.

Other than converting the Strings to integers, the logic of this section of code is identitcal to categories.

#### Creating the GameTiles and Final Jeopardy

Our last order of business is to process the remainder of the file and create our game tile and final jeopardy objets.

```gameTiles = {}

for line in fileLines[2:]:  # Slice off the first two lines
parts = line.split('::')

if parts in categories and int(parts) in points:
gameTile = GameTile(category=parts,
points=int(parts),
question=parts,

if parts not in gameTiles:
gameTiles[parts] = []
else:
gameTiles[parts].append(gameTile)

elif parts == 'FJ':
else:
raise InvalidGameFile
return gameTiles
```

We begin by creating a dict object that will hold our GameTile and FinalJeopardyTile objects. The categories will be used as the keys, and the value will be a list. Combining a dict and a list in this fashion let's use associate multiple values with a single key.

Now we are going to iterate through the remaining lines in the file. Notice that we use the slice operator [2:]. This is a neat Python trick that let's use exclude the first two entries in our list, which we do because we have already processed those lines at this point.

Next we need to validate the category and points that are associated with each question. We can check that parts (the category) is in our category list that we created earlier. The same holds true for points (parts) but notice that we convert to int here again. If the category and points are value, we move onto to create a GameTile using it's constructor.

Next, we need to check if gameTiles has a list associated with a category. If it doesn't have one yet, we need to create it. After that, we can look up a list with a category and then append the GameTile to that list. This keeps the questions organized by their category.

The elif block handles the final jeopardy case. If the parts == 'FJ', we have ran into our final jeopardy question. In this case, we create a special FinalJeopardyTile and associate it with the 'FJ' key in the dictionary. There is no list here because we only want to hold one final jeopardy object.

Finally we can return our newly constructed dictionary.

#### Running the code

Python make it easy to develop applications quickly because we can easily run modules as standalone applications.

```if __name__ == '__main__':
```

This code only executes when the module is ran on it's own. When it is run, it will look for a file called questions.txt in the same folder as the module. When run successfully, we get this output.

{'Earthquakes': [{'category': 'Earthquakes', 'points': 800, 'question': "... (continues)

You can get the entire code for this tutorial from here: python_tutorial_1

## Java Data Types

Almost everything we do in computer programming involves data. In many cases, the data itself is more valuable then the program. Many tax programs are written, but they all work on the same data. We may write tax software that displays fancy charts of your AGI over a period of 5 years, or we may write a program that calculates your net income. These programs are very worthwhile without data.

Java has two main ways of representing data. The first set of data types are called primitives. They are as follows

• byte (8-bit signed)
• short (16-bit signed)
• int (32-bit signed)
• long (64-bit signed)
• float (32-bit)
• double (64-bit)
• boolean (true/false)
• char (16-bit unicode characters)

## Whole Numbers

Let’s discuss each of these data types in turn starting with byte. A byte is smallest integer variable available to Java programmers and can hold values between -128 and 127. I generally use bytes in situations where I need to be conscious of my memory usage or when I’m programming on the web and need to transfer information from one site to another.

We can make a byte like this

```byte b = 120; //This variable stores the number 120
```

Next up the ladder is the short. Like bytes, shorts contain whole numbers between -32768 and 32767. Use shorts when you need to be concerned about memory usage.

Create a short by

```short s = 120; //This variable also store the number 120
```

The next primitive data type is int. This is one of the most commonly used numeric data type in Java programs. The int primitive data type stores values between -2147483648 and 2147483647.

Create an int by

```int i = 1; //This int variable holds the number 1
```

The long is the final whole number data type. At 64-bits this variable comes in as a monster that can store values between -9223372036854775808 and -9223372036854775807. Longs make great candidate in scientific applications where the program may end up processing large sets of data. I also see them used to store primary keys in database programming.

Create a long by

```long l = 100; //This long variable holds the number 100
```

## Decimals and Fractions

There are times where you need to store numeric data that is not a whole number. For example, in many cases you may need to use the number PI (3.14159) in a calculation. Our next two data types hold such numbers.

The first is float, which is a floating point number (hence the name). This is a 32-bit variable that can store 1.4E-45 to 3.4028235E38. Double is the more commoly used data type (64-bits) and stores values ranging from 4.9E-324 to 1.7976931348623157E308.

```float f = 5.99; //Make a float that stores the number 5.99
double d = -1.00; //Make a double that stores the number -1.00;
```

Never store money in these data types! The internal mechanics of these data types cause a loss in percision that can result in inaccuracies. Money should always get stored in the BigDecimal object.

## Non Numeric Data

Java has the ability to store non-numeric data. Sometimes all a programmer needs to know if when something it True or False. The boolean data type is used for such a purpose.

```boolean bTrue = true; //This boolean is true
bTrue = false; //Now it's false
```

We can also store unicode characters with the char type.

```char c = 'a'; //Store the letter a
char tab = '\t'; //Stores  a tab character
```

## Objects

Java also supports another data type that is not a primitive. These are called objects (to be discussed in another post). At this point there is one critical object to discuss that is called the String. String is a special kind of object that supports words and textual data.

```//Since Strings are objects, so we use the 'new' keyword to create them
String str = new String("Hi! I'm a string of letters");

//But you can also do this since Java has special built-in support for Strings
String anotherString = "Hi! I'm another String!";
```

## A working example

Below is a working example program that you can use to see the data types discussed above in action.

```
public class DataTypes {

public static void main(String [] args){
byte byteMin = Byte.MIN_VALUE;
byte byteMax = Byte.MAX_VALUE;

System.out.println("Bytes are the smallest data types (8-bit) and represent whole numbers.");
System.out.println("The smallest value you can store in a byte is " + byteMin + " and" +
" the maximum value is " + byteMax);
System.out.println("");

short shortMin = Short.MIN_VALUE;
short shortMax = Short.MAX_VALUE;

System.out.println("Shorts are one step larger than bytes (16-bit) and represent whole numbers.");
System.out.println("The smallest value you can store in a short is " + shortMin + " and" +
" the maximum value is " + shortMax);
System.out.println("");

int intMin = Integer.MIN_VALUE;
int intMax = Integer.MAX_VALUE;

System.out.println("Integers are one step larger than shorts (32-bit) and represent whole numbers.");
System.out.println("The smallest value you can store in an integer is " + intMin + " and" +
" the maximum value is " + intMax);
System.out.println("");

long longMin = Long.MIN_VALUE;
long longMax = Long.MAX_VALUE;

System.out.println("Longs are the largest of whole number data type (64-bit).");
System.out.println("The smallest value you can store in a long is " + longMin + " and" +
" the maximum value is " + longMax);
System.out.println("");

float floatMin = Float.MIN_VALUE;
float floatMax = Float.MAX_VALUE;

System.out.println("Floats represent decimal types. (32-bit)");
System.out.println("The smallest value you can store in a float is " + floatMin + " and" +
" the maximum value is " + floatMax);
System.out.println("");

double doubleMin = Double.MIN_VALUE;
double doubleMax = Double.MAX_VALUE;

System.out.println("Doubles also represent decimal types. (64-bit)");
System.out.println("The smallest value you can store in a double is " + doubleMin + " and" +
" the maximum value is " + doubleMax);
System.out.println("");

boolean booleanFalse = false;
boolean booleanTrue = true;

System.out.println("Booleans store true or false values.");
System.out.println("booleanFalse = " + booleanFalse);
System.out.println("booleanTrue = " + booleanTrue);
System.out.println("");

char charMin = Character.MIN_VALUE;
char charMax = Character.MAX_VALUE;

System.out.println("char represents a 16-bit unicode character");
System.out.println("The smallest char value is " + charMin + " and the largest is " + charMax);
System.out.println("");

String string = new String("I'm a string of text");
System.out.println("Java also has the Object data type. This is different from our other data types.");
System.out.println("It this example, we have and object that is a String. Strings hold text.");
System.out.println("string = " + string);
}
}
```

This is the output of the program when executed

```Bytes are the smallest data types (8-bit) and represent whole numbers.
The smallest value you can store in a byte is -128 and the maximum value is 127

Shorts are one step larger than bytes (16-bit) and represent whole numbers.
The smallest value you can store in a short is -32768 and the maximum value is 32767

Integers are one step larger than shorts (32-bit) and represent whole numbers.
The smallest value you can store in an integer is -2147483648 and the maximum value is 2147483647

Longs are the largest of whole number data type (64-bit).
The smallest value you can store in a long is -9223372036854775808 and the maximum value is 9223372036854775807

Floats represent decimal types. (32-bit)
The smallest value you can store in a float is 1.4E-45 and the maximum value is 3.4028235E38

Doubles also represent decimal types. (64-bit)
The smallest value you can store in a double is 4.9E-324 and the maximum value is 1.7976931348623157E308

Booleans store true or false values.
booleanFalse = false
booleanTrue = true

char represents a 16-bit unicode character
The smallest char value is  and the largest is ￿

Java also has the Object data type. This is different from our other data types.
It this example, we have and object that is a String. Strings hold text.
string = I'm a string of text
```