summer-2024: archive it

This commit is contained in:
Price Hiller 2024-08-31 02:13:09 -05:00
parent 50df5e961d
commit 09c66095ed
Signed by: Price
GPG Key ID: C3FADDE7A8534BEB
36 changed files with 11345 additions and 11 deletions

View File

@ -0,0 +1,69 @@
* Systems Programming Midterm Topics
1. Linux environment / shell commands
- Common commands
- Chmod/permissions
- Wildcards
- Input/output redirection
- Shell parsing steps
- Shell command resolution variables
- Shell vs environment and their inheritance
- Exit statuses
- Subshells / child shells
- Arithmetic (operators: expansion vs evaluation)
- Floating arithmetic in bash: how?
2. Bash Scripting
3. ~find~/~grep~
4. Regular expressions (BRE vs ERE)
5. ~sed~
NOTE: No AWK material will be covered on the exam
* Example Questions
1. Answer =True= or =False= for the following statements:
- [TRUE] The extended regular expression ~{0,1}~ is equivalent to the ~?~ quantifier?
- [FALSE] An exit status of ~0~ is used to indicate success.
- [FALSE] Given the string "abc123" the regex ~/[a-z]{1,3}/~ will produce a match of "a".
- [FALSE] The following loop will never execute:
#+begin_src bash
while [ 0 ]; do let i++; echo $i; done
#+end_src
- [TRUE] The following loop will never execute:
#+begin_src bash
while (( 0 )); do let i++; echo $i; done
#+end_src
- [TRUE] ~sed~ will emit the contents of the pattern space, including a trailing newline character, by default at the end of each input cycle.
- [FALSE] The following bash filename pattern will match all text files in the user's current directory:
#+begin_src bash
ls -la .*\.txt
#+end_src
- [TRUE] The ~source~ built-in executes the contents of a specified file within the current script (i.e. no subshell is utilized).
- [FALSE] ~grep~ uses extended regular expressions by default
2. Enter the octal number corresponding to the following Linux file permissions: ~rwxr-x---~
Answer: ~0750~
3. Write out the erroneous line numbers from the following script (hint there are six):
#+begin_src bash
data="./data"
org_data=/usr/local/courses/ssilvestro/cs3424/Spring21/assign1/
if [[ $# -eq 1 ]]; then
data = $1
else if [[ $# -eq 2 ]]; then
data = $1
orig_data = $2
fi
if [[! -d $data]]; then
echo "ERROR: data directory '$data' does not exist"
exit 1
fi
if [[ not -d $orig_data ]]; then
echo "ERROR: original data directory '$data' does not exist"
exit 1
fi
echo "rm -rf \"$data\"..."
rm -rf "$data"
echo "cp -r \"$org_data\" \"$data\"..."
cp -r "$orig_data" "$data"
#+end_src
Answer: ~4,5,6,7,9,13~

Binary file not shown.

View File

@ -0,0 +1,278 @@
Application
Programming
Hend Alkittawi
WELCOME!
Introduction
Welcome to Application Programming
WHAT IS APPLICATION PROGRAMMING?
Advanced application development in a current object-oriented language.
Introduction to the software life cycle, best programming practices, and modern
development tools.
This course is:
1.
An introduction to application development, including best practices
and object-oriented programming.
2.
Experience with new IDEs, repository sharing, and app building tools.
3.
The foundation you need for your first internship as a software
engineer.
WHAT IS APPLICATION PROGRAMMING?
Advanced application development in a current object-oriented language.
Introduction to the software life cycle, best programming practices, and modern
development tools.
This course is not the following courses:
1.
Software Engineering
2.
Mobile App Development
3.
Enterprise Software Engineering
4.
User Interface Design
WHAT IS APPLICATION PROGRAMMING?
Documentation
Testing
Coding
Engineering
Collaboration
WHAT IS APPLICATION PROGRAMMING?
35%
30%
20%
15%
Labs
Exams
Project
Quizzes
Refer to the schedule (here) for due dates.
LABS
<EFBFBD><EFBFBD>
5 Labs
-
All labs will be submitted on Canvas.
-
Labs
-
You may discuss algorithms and
must be completed individually.
approaches with others, but you may not
code together, share code, or share a
computer, under any circumstance.
QUIZZES
<EFBFBD><EFBFBD>
6 Quizzes
-
All quizzes are administered on Canvas.
-
Quizzes are not timed.
-
You may use online resources or any
materials.
-
Collaboration is not permitted.
-
Late quiz submissions are not accepted.
EXAMS
<EFBFBD><EFBFBD>
2 Exams
-
Midterm Exam on June 19, 2024 in class
during class time.
-
Final Exam on August 7, 2024 in class
during class time.
PROJECT
June
05
June
12
June
19
June
26
July
03
July
31
Aug
07
Aug
07
TEAM
FORMATION
TEAM
INTRODUCTION
PROJECT
PROPOSAL
PROJECT
PROTOTYPE
CODE
DESIGN
PROJECT
DEMO
FINAL
APPLICATION
SURVEY
2 points
2 points
2 points
2 points
4 points
2 points
4 points
2 points
● If you don't incorporate feedback from a previous assignment into the next one, you will
receive a 0 on that assignment.
● Your project grade depends on your contribution to the project!
IMPORTANT
You are expected to have
a solid understanding of
the following topics
-
Variables
Functions
Conditionals
Iterations
Arrays
IMPORTANT
The slides are used to guide
the flow of the class, and
are not meant to be the only
reference for completing the
labs and quizzes, studying
for the exams, or finishing
the project!
“Software development is hard,
but it opens the door to great
opportunities. Accept that it
is hard, embrace the
complexity, enjoy the ride.”
—Bruno”Sousa
RESOURCES
At UTSA we are committed to providing you with the support and resources
necessary to help you succeed in your academic journey. Here are some available
resources that you can utilize:
Computing Resources
Virtual desktop machines VDIs (available remotely!) - details on Canvas
Computers & Internet available in JPL and CS Main Lab (NPB 2.118)
Tutoring Resources
UTSA CS Tutoring on Slack and in the CS Main Lab
Library Resources
Textbooks are available (for all UTSA courses!) for short loans through the
John Peace Library (UTSA JPL) - print and ebook format.
Remember, these resources are designed to support and empower you. Do not
hesitate to reach out and take advantage of the opportunities available. We are
here to help you thrive and achieve your goals.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,305 @@
Application
Programming
Hend Alkittawi
Java Basics
Introduction to Java Concepts and
User-defined Java Classes
CONCEPTS
JAVA
OBJECT
- Released in early 1990s
- Defined by a class
- Object-oriented
- A class is a reusable
- Java SE, Java EE, Java ME
software components
- Non-primitive data type
CONCEPTS
JAVA APIs
- Application Programming
Interfaces
- Collections of existing
classes and methods in the
Java class libraries
JDK
- Java Development Kit
- Includes compiler, loader,
debugger, JRE, and other
tools for Java development
CONCEPTS
JVM
- Java Virtual Machine
- A part of the JRE that
IDE
- Integrated Development
Environment
executes bytecodes.
- A software that provides
- Bytecodes are platform
comprehensive facilities
independent (portable)
for software development.
WHY DO WE USE OBJECTS?
Let us discuss the difference between
Write a program to read n number of values in an array and
display them in reverse order.
Write a program to calculate x raised to the power n (xn).
Write a program to swap two numbers.
and
Small Scale Applications
OBJECT ANALOGY
BLUEPRINTS
My Car
color, …
accelerate, …
Your Car
Some Car
color, …
accelerate, …
color, …
accelerate, …
JAVA OBJECTS
public class Car {
Class Declaration
private int colorID;
private double speed;
public void setSpeed(int s){
speed = s;
}
public void accelerate(){
speed = speed + 70;
}
Attributes / Instance Variable(s)
Behaviors / Method(s)
public static void main(String[] args){
Car myCar = new Car();
myCar.setSpeed(50);
}
}
Car.java
Instantiation (building a Car object)
OBJECT ANALOGY
BIOLOGICAL
CLASSIFICATION
My Dog
breed, …
bark, …
Your Dog
breed, …
bark, …
Some Dog
breed, …
bark, …
JAVA OBJECTS
public class Dog {
Class Declaration
private int breedID;
Attributes / Instance Variable(s)
public void bark(){
System.out.println(Woof);
}
Behaviors / Method(s)
Dog.java
public static void main(String[] args){
Dog myDog = new Dog();
Instantiation (building a Dog obj)
myDog.bark();
}
}
THE String CLASS
-
The char primitive type stores one character of the Unicode
character set.
-
-
A string is a sequences of characters.
-
can be 0 or more characters long
-
"" is the empty string
The String class facilitates handling multiple characters at
once.
-
A String object can be declared in order to work with strings
String someStringObject = new String();
someStringObject = "HI";
THE String CLASS
-
Many String manipulation methods are available, here are some:
-
split() method to get an array of Strings from a String, based
on a delimiter. This object method takes a delimiter as a
parameter.
-
trim() method to clear off any additional space from the text.
This object method takes no parameters.
-
charAt() method to get the character at an index in the string
[starting with index 0]. This object method takes an index as
a parameter.
-
equals() method to check if two Strings contain the same text.
This object method takes a String object as a parameter.
THE String CLASS
-
Java also treats string literals as objects
-
-
A string literal is a quoted string: "Sam I am", "Hi", …, etc.
Examples:
String strObj = "This is \"a\" String";
strObj.charAt(0);
"HI
".trim();
escape sequence
"Hello".equals(strObj);
Note how we can create/work with string literals as String
objects.
JAVA OBJECTS
public class Dog {
private int breedID;
private String name;
public void bark(String dogBark){
System.out.println(dogBark);
}
}
public static void main(String[] args){
Dog myDog = new Dog();
myDog.bark(Woof);
}
Dog.java
Class Activity
public class SimpleLocation {
private double latitude;
private double longitude;
public void setLocation(double lat, double lon){
latitude = lat;
longitude = lon;
}
}
public static void main(String[] args){
SimpleLocation utsa = new SimpleLocation();
utsa.setLocation(32.9, -117.2);
}
What is
the value
of
longitude
?
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,154 @@
Application
Programming
Hend Alkittawi
Eclipse IDE
Introduction to Eclipse IDE
ECLIPSE IDE
Eclipse is an integrated development environment (IDE) used in
computer programming.
It is a popular IDE for Java development.
In Eclipse you can create new Java projects and import
existing projects to the workspace.
An Eclipse workspace is a folder on the disk where the project
and application files are stored.
Get eclipse here
CREATING A PROJECT IN ECLIPSE
1.
Open Eclipse and select/create a workspace > Launch
2.
If the welcome window appears, choose to hide it
3.
In the Package Explorer (top left area of IDE), right
click and select New > Java Project
4.
Name your project
5.
Ensure that the create module-info.java file is unchecked
6.
Click “finish”
Open Eclipse and
select/create a
workspace > Launch
If the welcome window
appears, choose to hide
it
Create a new Java project using the new project wizard (multiple ways)
Name your project (for labs, follow the lab guidelines!)
Ensure that the create module-info.java file is unchecked
CREATING A CLASS IN AN ECLIPSE PROJECT
1.
Expand your project
2.
Right-click on src > New > Class
3.
Name your class following Java naming convention
4.
To run your class, you need a main method. With that,
you can click the green “run” button at the top of the
IDE to run your program and see results in the console.
Create a new Java class
right-click on src > New > Class
give the class a name > finish
leave this as the default package
optional, can be added later
Edit and run your code
IMPORTING A PROJECT IN ECLIPSE
1.
If you have an Eclipse project in a zip file, unzip the
file
2.
Open Eclipse and select/create a workspace > Launch
3.
If the welcome window appears, choose to hide it
4.
In the Package Explorer (top left area of IDE), right
click and select Import …
5.
Select General > Existing Project Into Workspace > Next
6.
Browse to find the unzipped project directory > Finish
Import an existing project using the import project wizard (multiple ways)
Select General > Existing Project Into Workspace > Next
Browse to find the unzipped project directory > Finish
CODE DEMO
-
Create a Java project
and a Java class to
demo concepts!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,481 @@
Application
Programming
Hend Alkittawi
More on Java Classes
Best practices for Creating Java
Classes
BEST PRACTICES FOR CREATING JAVA CLASSES
STYLE
- identifier naming
- indentation
CONSTRUCTORS
- Ways to instantiate
objects
METHODS
- getters and setters
- equals()
- toString()
JAVADOC
- “special” Java
documentation
STYLE
visibility
type
class name
public class MyClass {
// attributes
private int intVar;
visibility
type
variable name
// methods
public void myMethod(String myString){
visibility
}
}
return
type
method
name
parameter parameter
type
name
METHODS
-
The syntax (rules) for declaring a method
visibility returnType methodName(parameterList)
-
visibility determines access
-
-
returnType is the type of data this method returns
-
-
public (all can access) or private (just this class can access)
if nothing is returned, use the keyword void
methodName starts with a lowercase word
-
it uses uppercase for the first letter of each additional word
(this is called “camel case”)
-
parameterList is any data we need to pass to the method
-
The ordering must be followed exactly
METHODS
-
Getter and setter methods are used to get and set the
value of the attributes.
-
Getters retrieve the value only
-
Setters update the value only
public class Account {
private double balance;
private String name;
public void setBalance( double balance ){
this.balance = balance;
}
public double getBalance(){
return this.balance;
}
// add a getter and a setter for name
}
● to use the class and its methods
public static void main(String[] args){
Account myAccount = new Account();
myAccount.setBalance(1000.0);
double balance = myAccount.getBalance();
}
METHODS
-
toString() method returns a String representation of objects.
An example of a toString() method for the Account class:
public class Account {
private double balance;
private String name;
public void setBalance( double balance ){
this.balance = balance;
}
public double getBalance() {
return this.balance;
}
// … getter and a setter for name
public String toString() {
return "Account info: name: " + name
+ " with balance: " + balance;
}
}
● to use the class and its methods
public static void main(String[] args){
Account myAccount = new Account();
myAccount.setName("Sam Adams");
myAccount.setBalance(1000.0);
System.out.println( myAccount );
}
METHODS
-
equals() method provides a way for users to compare instances
of your object to other instances. This also gives you control
over what is relevant to differentiate your objects.
-
● to use the class and its methods
private double balance;
private String name;
public static void main(String[] args){
Account myAccount = new Account();
Account yourAccount = new Account();
myAccount.setName(“Mia”);
myAccount.setBalace(10);
yourAccount.setName(“Ken”);
yourAccount.setBalance(100);
boolean check =
myAccount.equals(yourAccount);
}
public class Account {
public void setBalance( double balance ) {
this.balance = balance; }
public double getBalance() {
return this.balance; }
public String toString() {
return "Account info: name: " + name
+ " with balance: " + balance; }
public boolean equals( Account account2 ) {
return this.getName().equals( account2.getName());}
}
IMPORTANT
== is used for primitive types only
Objects define an object-method called equals()
2 == 5
objA.equals(objB);
Core: Drawing Memory Models with Objects - Memory Models, Scope,
and Starting the Project | Coursera
public class Account {
private double balance;
private String name;
public void setBalance( double balance ) {
this.balance = balance; }
public void setName( String name ) {
this.name = name; }
yourAccount
myAccount
name
name
balance
balance
public double getBalance() {
return this.balance; }
public String getName() {
return this.name; }
public boolean equals( Account account2 ) {
return this.getName().equals( account2.getName());
}
public String toString() {
return "Account info: name: " + name
+ " with balance: " + balance; }
}
public static void main(String[] args){
Account myAccount = new Account();
Account yourAccount = new Account();
myAccount.setName("Mia");
myAccount.setBalace(10);
yourAccount.setName("Ken");
yourAccount.setBalance(100);
boolean check =
myAccount.equals(yourAccount);
}
CONSTRUCTORS
-
Java requires a constructor call for every object that is created.
-
The keyword new creates a new object of a specified class by
calling a constructor.
-
A constructor is similar to a method but is called implicitly by
the new operator to initialize an objects instance variables when
the object is created.
-
In any class that does not explicitly declare a constructor, the
compiler provides a default constructor (which always has no
parameters).
-
When a class has only the default constructor, the classs
instance variables are initialized to their default value.
METHODS
-
You can provide your own constructor to specify custom
initialization for objects of your class.
-
A constructor must have the same name as the class.
-
If you declare a constructor for a class, the compiler will
not create a default constructor that class.
public
class Account {
private double balance;
private String name;
public Account( String name, double balance ){
this.name = name;
this.balance = balance;
}
/* … rest of class … */
}
● to use the class and its methods
public static void main(String[] args){
Account myAccount = new Account("Sam", 1000);
Account yourAccount = new Account("Jane", 2000);
}
JAVA GARBAGE COLLECTION
-
More than one variable may refer to the same data.
-
Java will clear out old data that no variables are referencing
-
-
This is known as garbage collection
Garbage collection is the process through which Java will
eventually clear out old data that no variables are
referencing.
JAVADOC
-
Javadoc comments are delimited between /** and */.
-
Javadoc comments enable you to embed program documentation
directly in your programs.
-
Javadoc utility program reads Javadoc comments and uses them
to prepare program documentation in HTML web-page format.
/**
* This is a Javadoc comment!
*/
JAVADOC
-
Javadoc comments annotations:
-
@author: designates the author of the code, belongs in the
class comment
-
@param: designates the parameter to a method, belongs in all
method comments which require parameters
-
@return: designates the returned value of a method, belongs in
method comments which return values
JAVADOC
Jav
ine
til t
l
u
M
men
Com
/**
* The Account class represents a bank account.
* @author CS3443
*/
public class Account {
/* attributes here .. a multi-line comment starts with /* .. be careful! */
/**
* sets the account balance
* @param balance, the account balance (double)
*/
public void setBalance(double balance){
this.balance = balance;
}
doc
a
Jav
c
ado
}
/**
* returns the balance for the account
* @return double, the account balance
*/
public double getBalance(){
return balance;
}
JAVADOC
-
To generate Javadoc in Eclipse
1.
Project > Generate Javadoc
2.
Destination: workspace/your_project/doc
3.
Next
4.
Select all “referenced archives and projects”
5.
Finish > Yes To All
6.
Open index.html
Project > Generate Javadoc
Destination:workspace/your_project/doc
> Next
Select all
> Finish
Yes To All
Open index.html
CODE DEMO
-
Create a Java class
following the best
practices
-
Generate Javadocs
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,431 @@
Application
Programming
Hend Alkittawi
Basic Java Data Structures
Arrays and ArrayLists, Wrapper
Classes and Static Methods
JAVA ARRAYS
-
Arrays in Java are objects which can be declared
-
by size
int[] myNumbers = new int[4];
Employee[] employees = new Employee[10];
-
by values directly (using an array initializer)
double[] myNumbers = {10.5, 20.34, 30.8, 40.12};
Account[] accounts = {accountOne, accountTwo};
-
Access values in an array by providing an index
double x = myNumbers[0];
-
Overwrite values at an index by using assignment
x = x + 5;
myNumbers[1] = x;
-
Loop over array elements to fill array, modify elements,… etc.
for (int i = 0; i < myNumbers.length; i++){
myNumbers[i] = i * 10;
System.out.println(myNumbers[i]);
}
JAVA ARRAYS
-
Recall the String manipulation methods
String stringA = "Im out of candy corn, send help!";
for( int i = 0; i < stringA.length(); i++ ){
char c = stringA.charAt(i);
System.out.print( c );
}
String[] sentences = stringA.split( "," );
System.out.println( sentences.length );
System.out.println( sentences[1].trim() );
JAVA ARRAYLISTS
-
An ArrayList object is an array that can grow or shrink as
needed! Use an ArrayList when you dont know how many of
something you need.
-
To create an ArrayList:
ArrayList<Integer> grades = new ArrayList<Integer>();
ArrayList<String> letters = new ArrayList<String>();
ArrayList<Employee> employees = new ArrayList<Account>();
ArrayList<Account> accounts = new ArrayList<Account>();
More on generics later!
JAVA ARRAYLISTS
-
Some useful methods for working with ArrayLists:
-
add() to add an object to the ArrayList
-
get(int index) to get an object from the ArrayList
-
contains() to check if an element is in the ArrayList
-
size() to get the number of elements currently in the ArrayList
-
remove(int index) to remove an object from an index in the
ArrayList
ArrayList<Integer> grades = new ArrayList<Integer>();
grades.add(5);
boolean present = grades.contains(7);
ArrayList<String> letters = new ArrayList<String>();
letters.add("CS3443");
WRAPPER CLASSES
-
Each primitive data type has a corresponding wrapper class,
which enables you to manipulate primitive type values as
objects. For example:
-
double has Double
-
int has Integer
-
char has Character
-
boolean has Boolean
WRAPPER CLASSES
-
The conversion between the primitive data type and wrapper
class type is mostly automatic
-
converting a primitive type to wrapper class is called
autoboxing.
-
converting a wrapper class object to primitive type is called
unboxing.
Double dbox = Math.sqrt(2);
double d = 1.0 / dbox;
// autoboxing
// unboxing
WRAPPER CLASSES
-
Wrapper classes provide several methods for manipulating data.
-
Some of the methods provided by these classes:
-
Double.parseDouble() to translate a String into a double value
-
Integer.parseInt() to translate a String into a int value
-
Character.getNumericValue() to translate a specified Unicode
character into the int value that it represents.
-
Note that there is no object associated with these methods
STATIC METHODS
-
Methods we have seen so far execute in response to method
calls on specific objects.
-
Sometimes a method performs a task that does not depend on an
object. These methods are called static/class methods.
-
To declare a method as static, place the static keyword before
the return type in the methods declaration.
public static void myMethod( arguments ) { method body }
-
To call a classs static method, specify the class name
followed by a dot (.), and the method name.
ClassName.methodName(arguments);
STATIC METHODS
-
Some of the static methods in the String class:
-
String.valueOf() to get the String value of a given variable
of a primitive type
String s = String.valueOf( 350.4 );
System.out.println( s.charAt(3) );
-
String.format() to format a string, similar to sprintf in C.
String.format("Account object: name = %s, balance =
$%.2f", name, balance);
STATIC METHODS
-
The class Math contains static methods for performing basic
numeric operations such as the elementary exponential,
logarithm, square root, and trigonometric functions
-
Here are a few class methods to try:
double absValPos = Math.abs(13)
double absValNeg = Math.abs(-13)
double minVal
= Math.min(3, 4)
OBJECT VS. STATIC METHODS
-
There are two types of methods in Java
-
-
Object methods
-
Associated with an object
-
Sent as a message to an object
-
Implicitly passed to the current object
-
Keyword: this
Class/Static methods
-
Not associated with a particular object
-
Sent as a message to a class
-
Keyword: static
When to use static methods - Stack Overflow
CLASS ACTIVITY
-
Given the strings below, which of the following lines contain
an object method?
String greeting = "HI";
String obvious = "This is a string";
String strWithSpace = "
1.
greeting.toLowerCase();
2.
String.valueOf(55);
3.
obvious.indexOf( "is");
4.
String.valueOf(17.8);
5.
strWithSpace.trim();
This is a string.
";
CLASS ACTIVITY
-
Given the strings below, which of the following lines contain
an object method?
String greeting =
"HI";
String obvious = "This is a string";
String strWithSpace =᳚ "
1.
greeting.toLowerCase();
2.
String.valueOf(55);
3.
obvious.indexOf("is");
4.
String.valueOf(17.8);
5.
strWithSpace.trim();
This is a string.
";
ARRAYS AND ARRAYLISTS IN A JAVA CLASS
-
In the case where a class variable contains a data structure,
multiple setter methods should be created.
-
Setter to set the value of the entire data structure
-
Setter/Adder to add just one value to the data structure
public class HelloWorld{
private String[] messages;
public void setMessages(String[] texts){
this.messages = texts;
}
public void addMessage (String text){
This.messages[0] = text;
}
public void addMessage (String text, int index){
// code to add the value of text to the array
}
}
Method Overloading
ENHANCED for STATEMENT
-
The enhanced for statement iterates through the elements of an
array/arraylist without using a counter!
-
for (paramType parameter : arrayName){
/* statements that read/obtain array elements, cannot
modify elements with the enhanced for statement */
}
parameter has a type and an identifier.
-
the type of the parameter must be consistent with the the type
of elements in the array
for (int x : myNumbers){
sum = sum + x;
}
JAVA PACKAGES
-
Related classes are typically grouped into packages so that
they can be imported into programs and reused.
-
The ArrayList class is part of the java.util package, so the
package need to be imported to your class to be able to use
the ArrayList class.
import java.util.ArrayList;
-
The package java.lang is implicitly imported by the compiler,
so it is not necessary to import classes in that package to
use them.
-
String and Math are examples of classes in java.lang package
CODE DEMO
-
Create class(es) to
demo the use of arrays
and arraylists!
Create a class to demo
static methods and
variables.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,281 @@
Application
Programming
Hend Alkittawi
File I/O
Working with File Input and Output
WORKING WITH DATA
-
Data can be stored on a computer in a file with a particular name!
-
There are two fundamentally different ways to store data in a
file:
-
Text files store data in text format: data items are represented in
human readable form, and can be edited using simple text editors.
-
-
*.txt, *.java, *.html, *.csv
Binary files store data in binary format: data items are
represented in bytes, and stored using an internal format that
requires special software to process.
-
*.jpeg, *.pdf
READERS, WRITERS, AND STREAMS
-
Java APIs provide two set of classes for handling input and
output.
-
If data is stored in text form (as a sequence of characters),
the Reader and Writer classes and their subclasses are used to
produce input and output.
-
If data is stored in binary form (as a sequence of bytes), the
InputStream and OutputStream classes and their subclasses are
used to produce input and output.
READERS, WRITERS, AND STREAMS
Reader
Writer
InputStream
OutputStream
InputStreamReader
PrintWriter
FileInputStream
FileOutputStream
FileReader
OutputStreamWriter
ObjectInputStream
ObjectOutputStream
FileWriter
PrintStream
READERS, WRITERS, AND STREAMS
-
To read text data from a disk file, create a FileReader object
-
To read binary data from a disk file create a FileInputStream
object
-
To write text data to a disk file, create a FileWriter object
-
To write binary data to a disk file create a FileOutputStream
object
THE Scanner CLASS
-
The Scanner class is flexible in that Scanner objects
can be attached to many different kinds of input.
-
-
input from the console
-
input from a file
Reader
When constructing a Scanner from a file object, the
Scanner automatically constructs a FileReader.
-
The Scanner class is part of the java.util package.
-
If the program is unable to locate the specified input
InputStreamReader
file, it will generate an exception which will prevent
the the program from continuing normal execution.
-
You can throw the exception or handle it with a
try/catch.
FileReader
THE Scanner CLASS
-
Some of the useful methods for reading input in the Scanner
class:
-
-
token-based processing
-
hasNext(): checks if the input has a token to read
-
next(): reads and returns the next token as a String
-
nextInt(): reads and returns an int value
-
nextDouble(): reads and returns a double value
line-based processing
-
hasNextLine(): checks if the input has a line to read
-
nextLine(): reads and returns the next line of input as a String
FILES AND File OBJECTS
-
To access a file from inside a Java program, you need to
construct an internal object that will represent the file.
-
Once you have constructed the object, you can call a number of
methods to manipulate the file.
File myFile = new File ("myFile.txt");
if (file.exists() && file.canRead()) {
// read the file!
}
-
The File class is part of java.io package.
READING A FILE WITH THE Scanner CLASS
-
Instead of instantiating objects with fixed values coded into
the application, we can instantiate objects by reading data
from a file.
-
create a data directory in your Eclipse project, and place the
file in it. Then, add code to read the data from a file
public void loadData(String fileName) throws FileNotFoundException {
File file = new File( "data/" + filename );
Scanner scan = new Scanner( file );
while( scan.hasNextLine() ) {
String line = scan.nextLine();
String[] tokens = line.split(",");
// do sth with the string and/or tokens, we will create an object based on the tokens!
MyClass obj = new MyClass(tokens[0], Double.parseDouble(tokens[1]), ...);
}
scan.close();
}
To create a data directory in your Eclipse project
right-click on project > New > Folder
Create a new file in the data directory, or copy and paste an existing file
right-click on data folder > New > File then enter data
OR
copy an existing file > right-click on data folder > paste
THE FileWriter CLASS
-
The FileWriter class can be utilized to write text data
to a file.
-
Writer
Use the write() method to write a String to the output
file.
-
If the program is unable to locate the specified input
file, it will generate an exception which will prevent
PrintWriter
the the program from continuing normal execution. You
can throw the exception or handle it with a try/catch.
public void writeFile(String filename) throws IOException{
File outFile = new File("data/" + filename);
OutputStreamWriter
FileWriter out = new FileWriter(outFile);
out.write("Success! \n");
out.write("Keep it up ...");
out.close();
}
FileWriter
CODE DEMO
-
Modify the classes
created in previous
sessions to demo file
I/O concepts.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,220 @@
Application
Programming
Hend Alkittawi
Project Overview
How to deliver a successful project!
PROJECT
June
05
June
12
June
19
June
26
July
03
July
31
Aug
07
Aug
07
TEAM
FORMATION
TEAM
INTRODUCTION
PROJECT
PROPOSAL
PROJECT
PROTOTYPE
CODE
DESIGN
PROJECT
DEMO
FINAL
APPLICATION
SURVEY
2 points
2 points
2 points
2 points
4 points
2 points
4 points
2 points
● If you don't incorporate feedback from a previous assignment into the next one, you will
receive a 0 on that assignment.
● Your project grade depends on your contribution to the project!
PROJECT PROPOSAL
-
The proposal will serve as the foundation for the
semester-long project
-
Project Title and Overview
-
Project Goals and Objectives
-
Target Audience
-
Scope of the Project
-
User Interface (UI) Design
-
Competition
-
Team Agreement
-
Conclusion
PAST LABS
PAST LABS
PROJECT PROTOTYPE
-
The prototype will help you visualize the user interface and
user experience of your app before development begins.
-
Adobe XD is a prototyping tool for user experience and
interaction designers to design websites, mobile apps, and
more.
-
Download Adobe XD and get started
-
Tutorial
CODE DESIGN
-
This assignment focuses on collecting the necessary data files
and obtaining a comprehensive overview of your application's
code design to ensure successful development of your
application.
-
Collect and organize all data files relevant to your
application. This may include: csv files, txt files, image
files, and any other data sources integral to your
application.
-
Application UML diagram (MVC)
PROJECT DEMO
-
The demo is to showcase the functionality and features of your
Android app through a demonstration video. This will require
effective communication and presentation skills to highlight
key aspects of your app.
-
This assignment also aims to cultivate critical thinking
skills through the subsequent feedback survey evaluation
process.
FINAL APPLICATION
-
The final submission of your Android application project is a
crucial step in showcasing your team's work. This assignment
focuses on the successful delivery of your project code while
adhering to specific guidelines and ensuring the projects
completeness.
-
I will be checking the GitHub repositories under the
organization for your final project submissions.
-
Code
-
Readme
-
UML
IMPORTANT
When given the
choice between
being right or
being kind
choose kind!
Check the Chocoholics
Anonymous Project Description
and Discuss the Basics of
Software Design Process
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,446 @@
Application
Programming
Hend Alkittawi
OOP Concepts
Introduction to Inheritance in Java
INHERITANCE
-
When creating a class rather than declaring completely new members
you can designate that the new class should inherit the members of
an existing class.
-
The existing class is called the superclass and the new class is
the subclass.
-
With inheritance the instance variables and methods that are the
same for all the classes in the hierarchy are declared in a
superclass.
-
In inheritance, a new class is created by acquiring an existing
classs members and possibly embellishing them with new or
modified capabilities.
public class Animal {
}
public class Dog extends Animal {
public class InheritanceDemo {
private String name;
private String breed;
public String getName() {
return name;
}
public String getBreed() {
return breed;
}
Animal animal = new Animal();
animal.eat();
public void setName(String name) {
this.name = name;
}
public void setBreed(String breed) {
this.breed = breed;
}
Dog dog = new Dog();
// setName() is an inherited method
dog.setName("Buddy");
public void eat() {
System.out.println(getName() +
" eats food.");
}
public void bark() {
System.out.println("The dog barks.");
}
// setBreed() is a method of Dog class
dog.setBreed("Golden Retriever");
}
public static void main(String[] args){
// eat() is an inherited method
dog.eat();
// bark() is a method of Dog class
dog.bark();
}
}
INHERITANCE
-
The direct superclass is the superclass from which the subclass
explicitly inherits.
-
An indirect superclass is any class above the direct
superclass in the class hierarchy, which defines the
inheritance relationships among classes.
-
In Java, the class hierarchy begins with a class Object which
every class in Java directly or indirectly extends.
-
Java supports only single inheritance in which each class is
derived from exactly one direct superclass.
INHERITANCE
-
Inheritance and constructors
-
Constructors are not inherited, a superclasss constructors are
still available to be called by subclasses.
-
Java requires that the first task of any subclass constructor is to
call its direct superclasss constructor to ensure that the
instance variables inherited from the superclass are initialized
properly.
-
Superclass constructor call syntax:
keyword super followed by a
set of parentheses containing the super class constructor arguments
which are you used to initialize the super class instance
variables.
public class Animal {
public class Dog extends Animal {
private String name;
private String breed;
public Animal(String name) {
this.name = name;
}
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public String getName() {
return name;
}
}
public static void main(String[] args){
Animal animal = new Animal("Hazel");
animal.eat();
Dog dog = new Dog("A Name", "A Breed");
public String getBreed() {
return breed;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println(getName() +
" eats food.");
}
public class InheritanceDemo {
// eat() is an inherited method
dog.eat();
public void setBreed(String breed) {
this.breed = breed;
}
}
public void bark() {
System.out.println("The dog barks.");
}
// bark() is a method of Dog class
dog.bark();
}
}
INHERITANCE
-
A subclass can add its own fields and methods; it is more specific than its
superclass.
-
A subclass exhibits the behavior of its superclass and can modify these
behaviors so that they operate appropriately for the subclass. A subclass can
customize methods that it inherits from its superclass to do this the
subclass overrides/redefines the superclass method with an appropriate
implementation.
-
To override a superclass method in a subclass, the subclass must declare a
method with the same signature as the superclass method.
-
When a subclass method overrides an inherited superclass method, the
superclass version of the method can be accessed from the subclass by
preceding the super-class method name with the keyword super and a DOT (.)
separator.
public class Animal {
public class Dog extends Animal {
private String name;
private String breed;
public Animal(String name) {
this.name = name;
}
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public String getName() {
return name;
}
public static void main(String[] args){
Animal animal = new Animal("Hazel");
animal.eat();
Dog dog = new Dog("A Name", "A Breed");
// eat() is an inherited method
dog.eat();
public String getBreed() {
return breed;
}
public void setName(String name) {
this.name = name;
}
// bark() is a method of Dog class
dog.bark();
public void setBreed(String breed) {
this.breed = breed;
}
public void eat() {
System.out.println(getName() +
" eats food.");
}
}
public class InheritanceDemo {
// toString() in Dog redefines the
// behavior of toString() in Animal
String s = dog.toString();
public void bark() {
System.out.println("The dog barks.");
}
@Override
public String toString() {
return "Name: " + getName();
}
}
@Override
public String toString() {
return super.toString() + " Breed: "
+ getBreed();
}
}
}
PUBLIC, PRIVATE AND PROTECTED KEYWORDS
-
A classs public members are accessible wherever the program
has reference to an object of that class or one of its
subclasses.
-
A classs private members are accessible only within the class
itself.
-
Using protected access modifier offers an intermediate level
of access between public and private; a superclasss protected
members can be accessed by members of that superclass, by
members of its subclasses and by members of other classes in
the same package.
PUBLIC, PRIVATE AND PROTECTED KEYWORDS
-
Public members of the superclass become public members of the
subclass and protected members of the superclass become
protected members of the subclass.
-
Methods of a subclass cannot directly access private members
of their superclass. Declaring private instance variables
helps you test, debug and correctly modify systems.
package inheritance;
public class Animal {
package inheritance;
public class Dog extends Animal {
private String name;
public String aString;
public String publicString;
protected String protectedString;
private String breed;
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public Animal(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public String getName() {
return name;
}
public void setBreed(String breed) {
this.breed = breed;
}
public void setName(String name) {
this.name = name;
}
public void bark() {
System.out.println("The dog barks.");
}
public void eat() {
System.out.println(getName() +
" eats food.");
}
private void testAccess() {
// String s0 = name; // invalid
String s1 = getName(); // indirect access
String s2 = publicString; // insecure
String s3 = protectedString; // valid
}
@Override
public String toString() {
return "Name: " + getName();
}
}
private void animalMethod() {
// method body
}
}
@Override
public String toString() {
return super.toString() + " Breed: "
+ getBreed();
}
package inheritance;
public class InheritanceDemo {
public static void main(String[] args){
Animal animal = new Animal("Hazel");
animal.eat();
// animal.animalMethod(); // inavlid
// animal.bark(); // invalid
// animal.name = "some string"; // invalid
animal.publicString = "some string";
animal.protectedString = "some string";
Dog dog = new Dog("A Name", "A Breed");
// eat() is an inherited method
dog.eat();
// bark() is a method of Dog class
dog.bark();
// toString() in Dog redefines the
// behavior of toString() in Animal
String s = dog.toString();
// dog.name = "some string"; // invalid
dog.publicString = "some string";
dog.protectedString = "some string";
}
}
CODE DEMO
-
Create classes to demo
inheritance concepts!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,184 @@
Application
Programming
Hend Alkittawi
OOP Concepts
Polymorphism
POLYMORPHISM
-
Polymorphism enables you to write programs that processes
objects that share the same superclass either directly or
indirectly as if they were all objects of the superclass.
-
The polymorphism occurs when a program invokes a method
through a superclass variable, at execution time the correct
subclass version of the method is called based on the type of
reference stored in the superclass variable.
-
A program can determine the type of an object at execution
time and act on that object accordingly.
POLYMORPHISM
Animal
Fish
🐟
Frog
🐸
Bird
🐦
xy coordinates
xy coordinates
xy coordinates
move()
move()
move()
POLYMORPHISM
Quadrilatera
l
Square
Trapezoid
Parallelogram
s
color
color
color
getPerimeter()
getPerimeter()
getPerimeter()
POLYMORPHISM
SpaceObject
LaserBeam
SpaceShip
Plutonian
picture
picture
picture
draw()
draw()
draw()
public class Animal {
public class PolymorphismDemo {
private String name;
public static void main(String[] args) {
public Animal(String name) { this.name = name; }
// Animal reference but Dog object
Animal myAnimal = new Dog("Thunder", 30);
// Output: Thunder the dog barks.
myAnimal.makeSound();
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// Animal reference but Cat object
myAnimal = new Cat("Whiskers", "Persian");
// Output: Whiskers the cat meows.
myAnimal.makeSound();
public void eat() { System.out.println(getName() + " eats food."); }
public void makeSound() { System.out.println("Animal makes a sound."); }
}
}
}
public class Dog extends Animal {
public class Cat extends Animal {
private int exerciseNeeds; // in min/day
private String breed;
public Dog(String name, int exerciseNeeds) {
super(name);
this.exerciseNeeds = exerciseNeeds;
}
public int getExerciseNeeds() {
return exerciseNeeds;
}
public void setExerciseNeeds(int exerciseNeeds) {
this.exerciseNeeds = exerciseNeeds;
}
@Override
public void makeSound() {
System.out.println(getName() + " the dog barks.");
}
}
public Cat(String name, String breed) {
super(name);
this.breed = breed;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed; }
@Override
public void makeSound() {
System.out.println(getName() + " the cat meows.");
}
}
CODE DEMO
-
Create classes to demo
polymorphism concepts!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,175 @@
Application
Programming
Hend Alkittawi
OOP Concepts
Java Abstract Classes
ABSTRACT CLASSES
-
Sometimes it's useful to declare classes for which you never
intend to create objects. These classes are called abstract
classes.
-
The purpose of an abstract class is to provide an appropriate
superclass from which other classes can inherit and thus share
common design.
-
Abstract classes are used only as superclasses in inheritance
hierarchies.
-
Abstract classes are incomplete, and cannot be used to
instantiate objects.
ABSTRACT CLASSES
-
To make a class abstract, declare it with the keyword abstract
public abstract class MyClass { … }
-
Abstract classes normally contain one or more abstract methods
-
An abstract method is an instance method with the keyword
abstract and its declaration
-
An Abstract method do not provide implementations
public abstract myMethod();
-
Constructors and static methods cannot be declared as
abstract.
ABSTRACT CLASSES
-
Subclasses must declare the missing pieces to become concrete
classes from which objects can be instantiated.
-
Each concrete subclass of an abstract superclass must provide
concrete implementations of each of the superclass abstract
methods.
public abstract class Shape {
public class AbstractClassDemo {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void display() {
System.out.println("This is a " + getType() + " shape. Its color is: " +
}
public abstract String getType();
public abstract void draw();
public static void main(String[] args) {
Circle circle = new Circle();
circle.setColor("red");
circle.setRadius(5.0);
circle.draw(); // implemented abstract method
circle.display(); // concrete method from
abstract class
}
}
getColor());
}
public class Circle extends Shape{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public void draw() {
System.out.println("Drawing a " + getColor() + " circle with radius " + getRadius() + ".");
}
@Override
public String getType() {
return "Circle";
}
}
public abstract class Shape {
private String color;
public Shape(String color) { this.color = color; }
public String getColor() { return color; }
public void setColor(String color) { this.color = color; }
public void display(){ System.out.println("This is a " + getType() + " shape. Its color is: " +
public abstract String getType();
public abstract void draw();
getColor()); }
}
public class Circle extends Shape{
public class AbstractClassDemo {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius; }
public static void main(String[] args) {
//Shape shape = new Shape("blue"); // invalid
Circle circle = new Circle("red", 5.0);
circle.draw(); // implemented abstract method
circle.display(); // concrete method from
abstract class
}
public double getRadius() { return radius; }
public void setRadius(double radius) { this.radius = radius; }
}
@Override
public void draw() {
System.out.println("Drawing a " + getColor() + " circle with radius " + getRadius() + ".");
}
@Override
public String getType() {
return "Circle"; }
}
CODE DEMO
-
Create classes to demo
abstract classes
concepts!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,137 @@
Application
Programming
Hend Alkittawi
OOP Concepts
Introduction to Java Interfaces
INTERFACES
-
Java interfaces are particularly useful for assigning common
functionality to possibly unrelated classes
-
Java interfaces offer a capability requiring that unrelated classes
implement a set of common methods
-
A Java interface describes a set of methods that can be called on an
object to tell it to perform some tasks or return some piece of
information
-
An interface should be used in place of an abstract class when there is
no default implementation to inherit, that is, no fields and no
concrete methods implementations
-
this allows objects of unrelated classes to be processed polymorphically
INTERFACES
-
An interface declaration begins with the keywords interface
and contains only constants and abstract methods
-
all methods declared in an interface are implicitly public
abstract methods
-
all fields are implicitly public, static, and final
public interface InterfaceName {
public static final dataType varName;
public abstract returnType interfaceMethod();
}
INTERFACES
-
To use an interface, a concrete class must specify that it
implements the interface and must declare each method in the
interface with the signature specified in the interface
declaration
-
Java does not allow subclasses to inherit from more than one
superclass, but it allows a class to inherit from one
superclass and implement as many interfaces as it needs
public class ClassName implements InterfaceName
or
public class ClassName extends SuperClass implements InterfaceName
where InterfaceName maybe a comma-separated list of interface names
public interface Drawable {
public void draw();
}
public class InterfaceDemo {
public static void main(String[] args) {
// Creating objects of different
// classes that implement Drawable
Drawable rectangle = new Rectangle(2.5, 7.2);
Drawable tree = new Tree("Oak", 5.5);
Drawable person = new Person("John", 30);
public class Tree implements Drawable {
private String type;
private double height;
public Tree(String type, double height) {
this.type = type;
this.height = height; }
// Array of Drawable objects
Drawable[] drawables = {rectangle, tree, person};
// getters and setters are omitted
// Drawing all drawable objects
for (Drawable drawable : drawables) {
drawable.draw();
}
@Override
public void draw() {
System.out.println("Drawing a tree with height " + getHeight() + " meters"); }
}
}
}
public class Rectangle implements Drawable{
private double length;
private double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width; }
// getters and setters are omitted
public void draw() {
System.out.println("Drawing a rectangle with length " + length + " and width " + width); }
}
CODE DEMO
-
Create classes to demo
interfaces concepts!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,694 @@
Application
Programming
Hend Alkittawi
UML Diagrams
UML Diagrams and Class Relationships
WHAT IS APPLICATION PROGRAMMING?
Documentation
Testing
Coding
Engineering
Collaboration
UML DIAGRAMS
-
UML: Unified Modeling Language
-
-
Graphical models of object-oriented software
What do you think such graphical models should include?
UML DIAGRAMS
-
UML: Unified Modeling Language
-
Graphical models of object-oriented software
Class Name
Variables
Methods
UML DIAGRAMS
-
Create the UML diagram for the Account.java class
public class Account {
private String name;
private double balance;
public Account(String name) {// method body here}
public void setName(String name) {// method body here}
public void setBalance(double bal) {// method body here}
public String getName() {// method body here}
public double getBalance() {// method body here}
}
Class Name
Variables
Methods
UML DIAGRAMS
-
Create the UML diagram for the Account.java class
public class Account {
private String name;
private double balance;
}
public Account(String name, double balance) {// method body here}
public void setName(String name) {// method body here}
public void setBalance(double bal) {// method body here}
Account
public String getName() {// method body here}
public double getBalance() {// method body here}
name
balance
Account()
getName()
setName()
getBalance()
setBalance()
UML DIAGRAMS
-
Create the UML diagram for the Account.java class
-
A <<interface>> tag indicates interface class
-
A <<constructor>> tag indicates constructor
-
Include variables data types
-
Include method parameters and their data type
-
Include method return data type
-
An underscore (_) indicates static
-
A minus(-) indicates private
-
A plus (+) indicates public
-
A hash (#) indicates protected
Account
- name: String
- balance: double
<<constructor>> Account( name: String, balance: double )
+ getName() : String
+ setName( name: String )
+ getBalance() : double
+ setBalance( amount: double )
UML DIAGRAMS
-
Create the UML diagram for the Account.java class
public class Account {
private String name;
private double balance;
public Account(String name, double balance) {// method body here}
public void setName(String name) {// method body here}
public void setBalance(double bal) {// method body here}
public String getName() {// method body here}
Account
public double getBalance() {// method body here}
}
- name: String
- balance: double
<<constructor>> Account( name: String, balance: double )
+ getName() : String
+ setName( name: String )
+ getBalance() : double
+ setBalance( amount: double )
UML Diagrams
-
Classes depend and interact with each other
-
UML diagrams can visually show the interactions and
dependencies between classes
-
Can you name relationships/dependencies between classes?
JAVA CLASSES
-
In a Java application classes are related to each other
-
In an is-a relationship an object of a subclass can also be treated
as an object of its superclass, or an object that implements an
interface can be treated as an object of the interface
(polymorphism).
-
-
Example: A SavingsAccount class that extends Account class
-
Example: An Invoice class that implements Payable interface
In a has-a relationship, an object contains as members references
to other objects (composition).
-
Example: An Employee class where an employee has one or more Date
objects
-
Example: A Bank class where a bank has one or more Account objects
UML Diagrams
-
Dependencies and relationships between classes can be
-
Dependency relationship
-
Unidirectional association
-
Bidirectional association
-
Aggregation relationship
-
Composition relationship
-
Realization relationship
-
Generalization relationship
UML DIAGRAMS
-
Generalization relationship
-
-
indicates inheritance between classes
ClassA has a generalization relationship
with ClassB implies
Freight
-
ClassA inherits from ClassB
Variables
-
ClassA is the subclass, and ClassB is
Methods
the superclass
-
declared in code as ClassA extends
Luggage
Cargo
ClassB
Variables
Variables
Methods
Methods
UML DIAGRAMS
-
Realization relationship
-
indicates inheritance, where ClassB is
an interface
-
<<interface>>
ClassA has a realization relationship with
Mammal
ClassB implies
Variables
-
ClassA inherits from ClassB
-
declared in code as ClassA implements
ClassB
Methods
Cat
Dog
Variables
Variables
Methods
Methods
UML DIAGRAMS
-
-
Composition relationship
-
indicates not-shared association
-
strong dependency
ClassA has a composition relationship with ClassB implies
-
ClassA is a container for a data structure of ClassB
-
there is not a super-sub / parent-child relationship between
ClassA and ClassB
-
if ClassA is deleted, ClassB need to be removed as well
Folder
- files: File[]
Methods
File
Variables
Methods
UML DIAGRAMS
-
Aggregation relationship
-
-
indicates shared association
ClassA has an aggregation relationship with ClassB implies
-
ClassA references a data structure of ClassB, but is not the
only reference
-
ClassA does not own ClassB
-
there is not a super-sub / parent-child relationship between
ClassA and ClassB
Wheel
Variables
Methods
Car
engine: Engine[]
wheels: Wheel[]
Methods
Engine
Variables
Methods
CLASS ACTIVITY
-
What does this UML tell you about the corresponding Java code?
Polygon
+ computeArea()
Triangle
Rectangle
Variables
Variables
Methods
Methods
CLASS ACTIVITY
-
What does this UML tell you about the corresponding Java code?
-
We have three Java classes
-
Polygon is an abstract class
-
computeArea() is an abstract method
-
A Rectangle is-a Polygon
-
-
Rectangle extends Polygon
Polygon
+ computeArea()
A Triangle is-a Polygon
-
Triangle extends Polygon
Triangle
Rectangle
+ computeArea()
+ computeArea()
VIOLET UML EDITOR
-
A free, cross-platform UML editor
-
You can get it here
-
We will be creating Class Diagrams
-
The UML diagram is saved as an html file and can be exported
as an image (*. png) file
Save As *.html
file
Save As *.png
file
UML DIAGRAMS
-
Unidirectional association
-
-
indicates dependency of only one class on another
ClassA has a unidirectional association with ClassB implies
-
ClassA uses and depends on ClassB, but ClassB does not
reference ClassA
-
at least one ClassB object is referenced in ClassA
-
there is an import statement in ClassA for ClassB
-
there is not an import ClassA statement in ClassB
Employee
Date
hireDate: Date
Variables
Methods
Methods
UML DIAGRAMS
-
Bidirectional association
-
-
indicates codependency of two classes
ClassA has a bidirectional association with ClassB implies
-
both depend upon each other
-
at least one ClassB object is referenced in ClassA
-
at least one ClassA object is referenced in ClassB
-
there is an import statement in ClassA for ClassB
-
there is an import statement in ClassB for ClassA
UserProfile
ProfilePicture
profilePic: ProfilePicture
userProfile: UserProfile
Methods
Methods
UML DIAGRAMS
-
Dependency relationship
-
a generalized connection between two classes if other
relationships are not meaningful!
-
-
We will primarily use it for classes referenced in main().
ClassA depends on ClassB implies one or more of the following
-
at least one ClassB object is referenced in ClassA
-
there is an import statement in ClassA for ClassB
-
at least one class method in ClassB is called by ClassA
AccountTest
+_main( args : String[] )
Account
Variables
Methods
UML DIAGRAMS
-
Dependencies and relationships between classes can be
-
General Dependency relationship
ClassA
ClassB
-
Unidirectional association
ClassA
ClassB
-
Bidirectional association
ClassA
ClassB
-
Aggregation relationship
ClassA
ClassB
-
Composition relationship
ClassA
ClassB
-
Realization relationship
ClassA
ClassB
-
Generalization relationship
ClassA
ClassB
UML DIAGRAMS
-
You might see UML diagrams in different formats
UML RESOURCES
-
UML relationships & associations
-
UML.org
-
The UML 2 class diagram - IBM Developer
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,60 @@
Application
Programming
Hend Alkittawi
Design Workshop
How to approach an app design!
INTRODUCTION
Think about the
classes you need to
create for a Payroll
System application!
*Reference Document
IMPORTANT
At the design stage in an
object oriented system you
will often find that certain
classes are closely related.
You should factor out common
instance variables and
methods and place them in a
superclass, then use
inheritance to develop
subclasses, specializing them
with capabilities beyond
those inherited from the
superclass.
DEMO
-
UML diagram for the Payroll System in Chapter 10
Eclipse Hint!
- To automatically generate getters
and setters, right-click in the
code editor > Source > Generate
getters and setters.
- This functionality is to save
expert developers some time. Use
it when you are at that level!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,300 @@
Application
Programming
Hend Alkittawi
Android Development
Introduction to Android Studio and
Android Apps Anatomy
GRAPHICAL USER INTERFACES (GUIs)
-
Console app vs. Mobile app!
>> Enter employee name: Ryan
>> Enter employee title: Product
Manager
>> Enter hire date: 06-03-2018
Employee Management
Employee Name
Employee Title
Employee Hire Date 📅
Submit
ANDROID STUDIO
-
Android Studio is an integrated development environment (IDE)
for building Android apps
-
Download and install Android Studio here
-
Installing Android Studio includes
-
Android SDK (Software Development Kit)
-
Android SDK tools and platform tools (for debugging & testing)
-
A system image for the Android emulator
-
JDK
HELLO, ANDROID STUDIO!
-
In Android Studio, create a new project
-
Select “Phone and Tablet” template → next
-
Select “Empty Views Activity” (different from “No Activity”) →
next
-
-
Package name: edu.utsa.cs3443.projectName → next
-
Language: Java → next
-
Minimum SDK: Android 8 (Oreo)
-
Finish → Finish
Android Studio may need to install several things if this is
your first project - be patient and do not close the IDE until
it is finished!
1
2
3
4
Project tool window
Editor tool window
HELLO, ANDROID STUDIO!
-
Layout Editor
-
drag and drop views in the Design mode
-
view the xml code by clicking the Code button in the top left
HELLO, ANDROID STUDIO!
-
Resource: a piece of your app that is
not code (e.g. image files, audio, XML)
-
Layout: Defines a set of UI objects and
the objects positions on the screen
-
View: UI objects (View is a superclass
of all UI components)
-
Inflate: parse an XML layout resource
and convert it to a hierarchy of View
objects
HELLO, ANDROID STUDIO!
-
Activity: a class in the Android SDK which represents an entry point to into your
app and is responsible for managing user interactions with a screen of information
-
Name your Activity class:
SomeNameActivity.java
-
Name your layout file:
activity_some_name.xml
In this example:
MainActivity.java
and
activity_main.xml
HELLO, ANDROID STUDIO!
-
MainActivity.java (default template)
-
onCreate() is called when an instance of the activity subclass is
created
-
setContentView() assigns this activity the UI it manages; it
inflates the layout & puts it on the screen, instantiating all views in
the layout file as defined by their attributes
package edu.utsa.cs3443.hello_world;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
ANDROID SDK
-
Immediately after installing Android Studio for the first time it
is likely that only the latest released version of the Android SDK
has been installed.
-
To install older versions of the Android SDK simply select the
checkboxes corresponding to the versions and click on the Apply
button.
-
This task can be performed by clicking on the More Actions link
within the welcome dialog or by clicking the Preferences menu
option, then selecting the SDK Manager option from the drop-down
menu,
-
select Android Oreo (8.0)
CREATING A VIRTUAL DEVICE
-
An Android application may be tested by installing and running
it either on a physical device or in an Android Virtual Device
(AVD) emulator environment.
-
As part of the standard Android Studio installation, several
emulator templates are installed allowing AVDs to be
configured for a range of different devices.
-
New AVDs are created and managed using the Android Virtual
Device Manager.
-
Tools > Device Manager (or the
icon)
ANDROID DEVELOPMENT RESOURCES
Our Textbook Forum
Documentation
https://developer.android.com/
Newsgroups And Forums
https://stackoverflow.com/questions/tagged/android
https://androidforums.com/
Development Tips
https://forums.bignerdranch.com/
https://android-developers.googleblog.com/
Videos And Tutorials
https://www.youtube.com/user/androiddevelopers
CODE DEMO
-
Create a HelloWorld
Android Application
using Android Studio
and walk through the
project content!
IMPORTANT
Run the HelloWorld
Android App on your
machine and/or VDI
before the end of
the week!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,312 @@
Application
Programming
Hend Alkittawi
MVC Architectural Pattern
Model-View-Controller Architectural
Pattern
CODE DEMO
-
Discuss the design of
a bank management app
MODEL-VIEW-CONTROLLER
Welcome to UTSA Bank Management System
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
1
Name: UTSA Bank
Account - name: Ash type: checking
Account - name: Sam type: saving
Account - name: Jen type: checking
Account - name: Mia type: saving
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
3
Enter account name:
Mia
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
2
Enter name and type:
Jim checking
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
1
Name: UTSA Bank
Account - name: Ash type: checking
Account - name: Sam type: saving
Account - name: Jen type: checking
Account - name: Jim type: checking
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
4
MODEL-VIEW-CONTROLLER
Welcome to UTSA Bank
Management System
What would you like to do?
View Accounts
Welcome to UTSA Bank
Management System
Welcome to UTSA Bank
Management System
Welcome to UTSA Bank
Management System
Here is a list of
accounts …
Enter Account Name
Enter Account Name
Select Account type
Add Account
Remove an Account
Add Account
Remove Account
Welcome to UTSA BankManagement System
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
1
Name: UTSA Bank
Account - name: Ash type: checking
Account - name: Sam type: saving
Account - name: Jen type: checking
Account - name: Mia type: saving
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
3
Enter account name:
Mia
What would you like to do?
1. Display Accounts
2. Add Account
3. Remove Account
4. Exit
2
Enter name and type:
Jim checking
Welcome to UTSA Bank
Management System
What would you like to do?
View Accounts
Add Account
Remove an Account
Welcome to UTSA Bank
Management System
Here is a list of
accounts …
Welcome to UTSA Bank
Management System
Welcome to UTSA Bank
Management System
What would you like to do?
Enter Account Name
View Accounts
Select Account type
Add Account
Remove an Account
Add Account
Welcome to UTSA Bank
Management System
What would you like to do?
Welcome to UTSA Bank
Management System
Enter Account Name
View Accounts
Add Account
Remove an Account
Remove Account
MODEL-VIEW-CONTROLLER
-
An architectural pattern captures the design structures of
various systems and elements of software so that they can be
reused.
-
Android applications can be designed around an architecture
called model-view-controller or MVC.
-
In MVC, all objects in your application must be a model
object, a view object, or a controller object.
-
MVC helps you design and understand an application, and makes
classes easier to reuse.
MODEL-VIEW-CONTROLLER
-
MVC is an architectural pattern which helps separate
-
the application logic from the user interface
-
the control between the user interface and the application
logic
model
data storage,
integrity, consistency,
queries & mutations
controller
view
receive, interpret &
validate input, create &
update views, query and
modify models
presentation assets &
code
user
MODEL
-
The model represents the data and the rules that govern access
to and updates of this data, and the business logic
-
A model often serves as a software approximation of a
real-world process
-
Designed and implemented as one or more classes
-
typically model the things your app is concerned with such as
a user, a product, a photo, at television show, … etc.
-
Model objects have no knowledge of the UI; its purpose is
holding and managing data.
VIEW
-
View objects know how to draw themselves on the screen
-
The view renders the contents of a model
-
The view specifies exactly how the model data should be
presented
-
If the model data changes, the view must update its
presentation as needed
-
Android provides a wealth of configurable view classes. You
can also create custom view classes.
CONTROLLER
-
Controller objects tie the View and Model objects together.
They contain application logic.
-
Controllers are designed to respond to various events
triggered by view objects and to manage the flow of data
between the model layer and the view layer.
-
The controller translates the user's interactions with the
view into actions that the model will perform
-
In Android, a controller is typically a subclass of Activity,
Fragment, or Service.
-
Implemented as one or more classes
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,652 @@
Application
Programming
Hend Alkittawi
Android Development
Building Our First Android App
OUR FIRST ANDROID APPLICATION
-
What do you think we need to build this app?
Rowdy Quiz
Trivia Question Here
True
False
Next
OUR FIRST ANDROID APPLICATION
-
What do you think we need to build this app?
-
-
Model Objects
-
Question.java
-
QuizBank.java
View Objects
-
-
Rowdy Quiz
layout xml file
Controller Objects
-
Trivia Question Here
MainActivity.java
True
False
Next
OUR FIRST ANDROID APPLICATION
Rowdy Quiz
Trivia Question Here
True
False
Next
OUR FIRST ANDROID APPLICATION
-
Model Objects
-
After you create the project in Android
Studio, create a model package
-
In edu.usta.cs3443.projectname
-
right-click on the package
-
select New > Package
-
set the package name to model
-
create/place the model classes within
the model package
OUR FIRST ANDROID APPLICATION
-
View Objects
-
layout xml file
-
Set up the layout (xml or drag and drop)
-
Rowdy Quiz
LinearLayout (Vertical)
-
TextView - for Rowdy Quiz
-
TextView - for Trivia Question
-
LinearLayout (Horizontal)
-
-
Button - for True
-
Button - for False
Trivia Question Here
True
False
Button - for Next
Next
TIPS FOR WORKING WITH LAYOUT XML FILES
-
Views may have an integer id associated with them. These ids
are typically assigned in the layout XML files, and are used
to find specific views within the view tree.
-
Add id attributes for views that your code will be
interacting with
<TextView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:padding ="24dp"
android:text="trivia question here!"
android:id="@+id/question_text"
/>
TIPS FOR WORKING WITH LAYOUT XML FILES
-
Add strings to the string.xml resource file
-
res > values > strings.xml
<resources >
<string name="app_name" >Rowdy Quiz</ string>
<string name="false_button" >False</ string>
<string name="true_button" >True</string>
<string name="next_button" >Next</string>
</resources >
-
Use these strings with your views
<TextView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:padding ="24dp"
android:text="@string/app_name"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/app_name" />
<TextView
android:id="@+id/question_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="trivia question here!" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/true_button" />
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/false_button" />
</LinearLayout>
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/next_button" />
</LinearLayout>
activity_main.xml
Rowdy Quiz
Trivia Question Here
t
ex
n_t
tio
id:
s
que
to
but
True
n
ton
_
id:
e
tru
ut
e_b
als
f
id:
Next
on
id:
False
nex
t
tt
_bu
OUR FIRST ANDROID APPLICATION
-
Controller Objects
-
GUIs are built from GUI components called
views
-
A controller class manages the flow of data
Rowdy Quiz
between the model layer and the view layer
-
When the user interacts with GUIs, an event
object is create
-
The event object is dispatched to an event
handler (listener)
-
Trivia Question Here
A controller object listens and responds to
these events
True
False
Next
OUR FIRST ANDROID APPLICATION
-
Controller Objects
-
An Activity (controller) class utilizes the following to be
able to manage the flow of data, listen and respond to events
-
findViewById() method to get references to the inflated View
objects
-
getId() method to get the ID of a view
-
OnClickListener interface to set listeners on View objects to
respond to user actions
-
Rowdy Quiz
-
// some code is omitted, refer to full code on Github
public class MainActivity extends AppCompatActivity {
private QuizBank quizBank;
Controller Objects
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createQuizBank();
displayQuestion();
manage data flow
Button trueButton = findViewById(R.id.true_button);
Button nextButton = findViewById(R.id.next_button);
trueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(getAnswer())
// display a “Yay!” message
else
// display a “Try again!” message
} });
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { displayQuestion(); }
});
listen to events
respond to events
}
private void createQuizBank(){
quizBank = new QuizBank();
quizBank.loadQuestions();}
manage data flow
private void displayQuestion(){
quizBank.getCurrentQuestion();
TextView questionText = findViewById(R.id.question_text);
questionText.setText( getQuestion() ); }
manage data flow
private String getQuestion(){
return quizBank.getCurrentQuestionText(); }
private boolean getAnswer(){
return quizBank.getCurrentQuestionAnswer(); }
}
// some code is omitted, refer to full code on Github
public class MainActivity extends AppCompatActivity {
private QuizBank quizBank;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nts
createQuizBank();
displayQuestion();
ve
o e
t
n
Button trueButton = findViewById(R.id.true_button);
te
lis
Button nextButton = findViewById(R.id.next_button);
trueButton.setOnClickListener(new View.OnClickListener() {
ts
ven
@Override
e
o
public void onClick(View view) {
d t
n
o
if(getAnswer())
p
res
// display a “Yay!” message
else
// display a “Try again!” message
} });
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { displayQuestion(); }
});
w
}
private void createQuizBank(){
quizBank = new QuizBank();
quizBank.loadQuestions();}
age
man
a
dat
flo
low
age
private void displayQuestion(){
man
quizBank.getCurrentQuestion();
TextView questionText = findViewById(R.id.question_text);
questionText.setText( getQuestion() ); }
private String getQuestion(){
return quizBank.getCurrentQuestionText(); }
private boolean getAnswer(){
return quizBank.getCurrentQuestionAnswer(); }
}
a f
dat
Rowdy Quiz
Trivia Question Here
t
ex
n_t
tio
id:
s
que
e_b
tru
:
d
i
id:
True
on
utt
id:
n
tto
bu
se_
fal
ton
ut
t_b
nex
False
Next
OUR FIRST ANDROID APPLICATION
-
Working with Toasts
-
a Toast is a pop-up message that informs
the user of something but does not require
any input or action
-
to create a Toast message use the makeText()
method
-
the show() method shows the Toast view on the
screen
Toast.makeText(view.getContext(), "Yaaay!", Toast.LENGTH_LONG).show();
// some code is omitted, refer to full code on Github
public class MainActivity extends AppCompatActivity {
private QuizBank quizBank;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// some code is omitted, refer to full code on Github
public class QuizBank {
private ArrayList<Question> questions;
private int qIndex;
private Question currentQuestion;
public QuizBank(){
questions = new ArrayList<Question>();
qIndex = 0;
currentQuestion = null; }
createQuizBank();
displayQuestion();
Button trueButton = findViewById(R.id.true_button);
Button nextButton = findViewById(R.id.next_button);
trueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(getAnswer())
// display a “Yay!” message
else
// display a “Try again!” message
} });
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { displayQuestion(); }
});
public int getqIndex() { return qIndex; }
public void setqIndex(int qIndex) { this.qIndex = qIndex; }
public Question getCurrentQuestion(){
if(getqIndex() >= 0 && getqIndex() < questions.size() ) {
currentQuestion = questions.get(getqIndex());
setqIndex(getqIndex() + 1);
} else{
setqIndex(0);
currentQuestion = questions.get(getqIndex());
}
return currentQuestion;
}
}
private void createQuizBank(){
quizBank = new QuizBank();
quizBank.loadQuestions();}
public String getCurrentQuestionText(){
return currentQuestion.getQuestion();}
public boolean getCurrentQuestionAnswer(){
return currentQuestion.getAnswer(); }
private void displayQuestion(){
quizBank.getCurrentQuestion();
TextView questionText = findViewById(R.id.question_text);
questionText.setText( getQuestion() ); }
public void loadQuestions() {
addQuestion(new Question("Is our mascot a roadrunner", true));
addQuestion(new Question("Is UTSA in San Antonio", true));
}
private String getQuestion(){
return quizBank.getCurrentQuestionText(); }
private boolean getAnswer(){
return quizBank.getCurrentQuestionAnswer(); }
}
public void addQuestion(Question question){
questions.add(question);
}
}
CODE DEMO
-
Create and run the
Rowdy Quiz App in
Android Studio
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,288 @@
Application
Programming
Hend Alkittawi
Android Development
Building An Application That
Utilizes Data
ROWDY QUIZ APP
-
We created the Rowdy Quiz app, with hard-coded questions
-
Now, it is time to load the questions from a data file
-
We will also add a logo to our screen
WORKING WITH DATA
Reader
Writer
InputStream
OutputStream
InputStreamReader
PrintWriter
FileInputStream
FileOutputStream
FileReader
OutputStreamWriter
ObjectInputStream
ObjectOutputStream
FileWriter
PrintStream
WORKING WITH DATA
-
Classes utilized for reading and writing data in Android
-
Activity
-
AssetManager
-
InputStream
-
OutputStream
READING DATA FROM A FILE
-
To read data from a file:
-
place the file in the Assets folder
- app > New > Folder > Assets Folder (do not change the folder
location)
READING DATA FROM A FILE
-
Under the model package, modify QuizBank.java
-
Modify the loadQuestions() method to create the questions from a data
(*.csv) file
-
the method uses the Activity, AssetManger and InputStream classes to read
the data from the file
public void loadQuestions(MainActivity activity){
AssetManager manager = activity.getAssets();
Scanner scan = null;
String filename = "test.csv";
try {
InputStream file = manager.open(filename);
scan = new Scanner(file);
// do something with the file data
}
catch (IOException e) { // handle exception }
}
READING DATA FROM A FILE
-
For the controller, modify MainActivity.java
-
onCreate() calls the createQuizBank() method to load the questions
in the quiz bank
-
createQuizBank() calls the loadQuestions() method which requires
an AssetManager to load the data from the *.csv file in the
Assets folder
-
Get an AssetManager object from MainActivity using
activity.getAssets()
private void createQuizBank(){
quizBank = new QuizBank();
quizBank.loadQuestions(this);
}
READING DATA FROM A FILE
-
In QuizBank.java
public void loadQuestions(MainActivity activity){
AssetManager manager = activity.getAssets();
Scanner scan = null;
try {
InputStream file = manager.open("test.csv");
scan = new Scanner(file);
// do something with the file data
}
catch (IOException e) {
// handle exception
}
}
-
In MainActivity.java
private void createQuizBank(){
quizBank = new QuizBank();
quizBank.loadQuestions(this);
}
ROWDY QUIZ APP UML
WRITING DATA TO A FILE
-
The Assets folder is read-only, we cannot write data to the
files in the Assets folder
-
To write data to a file, create a file in the AVD memory.
-
Once created, the file can be located in the AVD memory by
navigating to View > Tool Windows > Device Explorer then data
> user > 0 > edu.utsa.cs3443.projectName > files
WRITING DATA TO A FILE
-
Under the model package, modify QuizBank.java
-
add the saveData() method to save data to a (*.txt) file
-
the method uses the Activity and OutputStream classes to read the data
from the file
public void saveData(MainActivity activity){
try {
OutputStream out = activity.openFileOutput(filename, Context.MODE_PRIVATE );
out.write("test writing to a file".getBytes(StandardCharsets.UTF_8));
out.close();
} catch (IOException e) {
System.out.println("Failed to write data");
}
}
WRITING DATA TO A FILE
-
For the controller, modify MainActivity.java
-
onCreate() calls the createQuizBank() method to load the questions
in the quiz bank
-
saveData() method requires an Activity to access the AVD
memory
quizBank.loadQuestions(this);
quizBank.saveData(this); // call it wherever your code needs to save data
READING DATA FROM A FILE
-
In QuizBank.java
public void saveData(MainActivity activity){
try {
OutputStream out = activity.openFileOutput(filename, Context.MODE_PRIVATE );
out.write("test writing to a file".getBytes(StandardCharsets.UTF_8));
out.close();
} catch (IOException e) {
System.out.println("Failed to write data");
}
}
-
In MainActivity.java
quizBank.saveData(this);
WORKING WITH DATA
-
What if we would like to update data in a file from the Assets
folder?
-
The Assets folder is read-only, we cannot write data to the
files in the Assets folder
-
A work around this is to create a copy of the file from the
Assets to the AVD memory, then use the “copy file” for reading
and writing data.
ADDING IMAGEVIEWS TO THE LAYOUT
-
Use an ImageView in the layout file to display an
image on the screen
-
ImageViews can display images from the drawable
folder
-
-
Place the image file under res > drawable
The ImageViews src attribute specifies the image
that the ImageView will display
<ImageView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:src="@drawable/rowdylogo"/>
CODE DEMO
-
Walk through the
Android App in Android
Studio
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,371 @@
Application
Programming
Hend Alkittawi
Version Control
Introduction To Git And Github
INTRODUCTION
We watched a few videos from the following course on
Udacity:
Version Control With Git
VERSION CONTROL
-
Collaborative software development necessitates a system for
source control and versioning!
-
A version control system facilitates simultaneous updates to
the same software and manages any conflicts created!
-
There are a few version control system options
-
CVS - Concurrent Versions System
-
SVN - Apache Subversion
-
GIT - a distributed VCS
(not the only one)
VERSION CONTROL
GIT
-
Developed by Linus Torvalds around 2005
-
Open source, under the GNU GPL (General Public License)
-
Distributed, in that every directory on every computer is a
full-fledged repository
-
It has a complete history, version-tracking capabilities
-
Independent of network access, or a central server
-
Use as command-line or via GUI
GIT
-
To create a local Git Repo
1.
Create a new project directory
mkdir WorkingDir
2.
Move into that new directory
cd WorkingDir
3.
Initialize Git repository
git init
4.
Create/edit project files
5.
Stage files in the project directory
git add .
6.
Commit tracked files in Git storage
git commit -m "a msg"
Git Repository
Working Directory
file1
file2
Staging Area
GITHUB
-
Web-based Git repository hosting service
-
Provides cloud storage, public/private
repos, free accounts
-
Home to lots of open source software!
-
To use Github
1.
Access a remote repository on Github.com
2.
Pull down the latest version of the code to local
3.
Add edited files to the source code
4.
Commit edits to the local version
git commit -m "short msg"
5.
Push the changes out to the server
git push
git pull
git add File.java
VERSION CONTROL
-
Summary of Git Terminology
-
Repo - repository
-
Init - initialize a repository
-
Commit
-
Push/Pull
-
Clone - copy a remote repo locally
-
Branch - a separate version of the main repo that allows
working on different parts of a project without impacting the
main branch.
VERSION CONTROL
-
Git and Github
-
You can choose how you want to use Git and Github
-
Command line
-
Browser
http://github.com
-
GitHub Desktop
http://desktop.github.com
-
IDE
VERSION CONTROL
-
Some useful resources
-
Hints for using eGit (Eclipse plugin)
-
Resolving merge conflicts
-
Effective Git:
-
Tutorial:
https://git-scm.com/book/en/v2
https://try.github.io/
README FILES
-
A code readme file should include dependencies, description of
functionality, etc.
-
A repo readme file should describe project(s) in the repo,
contributors, functionality, license(s), contribution
guidelines, known issues, ….
-
A README file is created using markdown language!
-
Example: README.md template · GitHub
README FILES
-
More Readme
-
A Beginners Guide to writing a Kickass README ✍ | by Akash
-
Top ten reasons why I won't use your open source project |>
Changelog
-
GitHub - hackergrrl/art-of-readme: :love_letter: Things I've
learned about writing good READMEs.
-
How To Write A Great README
-
GitHub - jehna/readme-best-practices: Best practices for writing a
README for your open source project
-
zalando-howto-open-source/READMEtemplate.md at master
TUTORIAL
Using Git/Github in
Android Studio
Generate a personal access token and save it somewhere! (Under your
Github account > Settings > Developer Settings)
Check the repository created under your team in CS3443 Github
organization OR create your own repository under your account
Create your project in Android Studio then create a local Git repo
(Android Studio > VCS > Enable Version Control Integration, select Git)
Create your project in Android Studio then create a local Git repo
(Android Studio > VCS > Enable Version Control Integration, select Git)
Stage files (Right click on app > Git > Add)
Commit to local repo (Right click on app > Git > Commit Directory…) and
add the unversioned files
Rename local branch to main (to match the remote branch name)
-- IMPORTANT --
Copy the https URL for the remote repo
Add the remote repo
Add the remote repo
Add the remote repo
Fetch
Note: Since we added a README to the remote repo we need Rebase before
we Pull. You do not need to Rebase before you Pull if you did not
create a README in the remote repo - you can skip slides 27 and 28.
Rebase (we are just using it here because our local and remote repos
initially do not have a “common history”)
Pull from remote repo
Pull from remote repo
Push to remote repo
Push to remote repo
Modify file(s) on Github (similar to if someone else modifies the files)
Modify file(s) on Github (similar to if someone else modifies the files)
Pull changes to local repo
Modify file(s) locally
Stage, commit and push to remote repo (like above)
Check the remote repo
CODE DEMO
-
Show how to use Git in
Android Studio
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,599 @@
Application
Programming
Hend Alkittawi
SOLID Principles
Applying SOLID Principles In Object
Oriented Design
WHY SOLID PRINCIPLES?
-
Watch this video from the Coursera course Software Development
Processes and Methodologies
-
The content for this lecture is based on a series of
papers/book chapters by Robert Martin
-
You might find these references useful
-
Uncle Bob SOLID principles
-
SOLID Design Principles with Java Examples | Clean Code and
Best Practices | Geekific
SYMPTOMS OF ROTTING DESIGNS
-
-
Rigidity
-
Difficult to change in even simple ways
-
Changes cause a cascade of issues in dependent modules
Immobility
-
-
Inability to reuse modules
Fragility
-
Tendency for changes to cause problems in many areas
-
New problems often in areas with no conceptual relationship to the original
change
-
Viscosity
-
Viscosity of design → It is harder to make changes that preserve the original
design
-
Viscosity of environment → Development environment is slow and inefficient
CHANGING REQUIREMENTS
-
Requirements change in a way that was not anticipated by the
original design
-
The requirements document is the most volatile document in a
project
-
We need to make our designs resilient to changes and protect
them from rotting
-
Tree Comic
DEPENDENCY MANAGEMENT
-
Rot is caused by changes that introduce new and unplanned for
dependencies
-
Rigidity, Fragility, Immobility, and Viscosity are directly or
indirectly caused by improper dependencies between software
modules
-
To avoid rot, dependencies between modules in an application
must be managed
-
This management consists of dependency firewalls across which
dependencies do not propagate
SOLID PRINCIPLES
-
SOLID is a way to manage dependencies
-
The Single Responsibility Principle (SRP)
-
The Open Closed Principle (OCP)
-
The Liskov Substitution Principle (LSP)
-
The Interface Segregation Principle (ISP)
-
The Dependency Inversion Principle (DIP)
SOLID PRINCIPLES
-
The Single Responsibility Principle (SRP)
-
There should never be more than one reason for a class to
change
-
If a class has more than one responsibility, then there will
be more than one reason for it to change
-
-
A class should have one responsibility
Multiple responsibilities can become coupled
-
Changes to one responsibility can impair the class' ability to
meet its other responsibilities
SOLID PRINCIPLES
-
The Single Responsibility Principle (SRP)
-
An example of how a class that has too many responsibilities
can be split into multiple classes
-
If needed, a class can have objects from the other classes
Employee
Employee
EmployeeDB
EmployeeReport
name
salary
name
salary
name
salary
name
salary
// payroll methods
// hr methods
// DB methods
// pay methods
// DB methods
// hr methods
SOLID PRINCIPLES
-
The Open Closed Principle (OCP)
-
Software entities should be open for extension but closed for
modification
-
Design modules that never change
-
When requirements change, extend the behavior of a module by
adding new code not by changing code that already works
-
Modules that conform to OCP
-
Have behaviors that can be extended
-
Have source code that does not change
SOLID PRINCIPLES
-
The Open Closed Principle (OCP)
-
Example for a design that is not closed for modification
public abstract class Shape {
public abstract String getShapeType();
}
public class Circle extends Shape {
private String shapeType = “Circle”;
private double radius;
private Point center;
}
public String getShapeType(){
return shapeType;
}
public class Square extends Shape {
private String shapeType = “Square”;
private double side;
private Point topLeftCorner;
}
public String getShapeType(){
return shapeType;
}
public void drawAllShapes(Shape[] shapes){
for(int i = 0; i < shapes.length; i++){
Shape shape = shape[i];
switch (shape.getShapeType()){
case "Circle":
drawCircle(shape);
break;
case "Square":
drawSquare(shape);
break;
default:
System.out.println("Unknown shape: "
+ shape.getShapeType());
}
}
}
What if we
add more
shapes?
SOLID PRINCIPLES
-
The Open Closed Principle (OCP)
-
Example how the previous design can be modified to be closed
for modifications
public abstract class Shape {
public abstract void draw();
}
public class Circle extends Shape {
private double radius;
private Point center;
}
public void draw(){
// code to draw here;
}
public class Square extends Shape {
private double side;
private Point topLeftCorner;
}
public void drawAllShapes(Shape[] shapes){
for(int i = 0; i < shapes.length; i++){
Shape shape = shape[i];
shape.draw();
}
}
public void draw(){
// code to draw here;
}
What if we
add more
shapes?
SOLID PRINCIPLES
-
The Liskov Substitution Principle (LSP)
-
Subclasses should be substitutable for their base classes
-
Example for a subclass that is not substitutable for its base
class
public class Rectangle {
private double width;
private double height;
}
public void setWidth(double width) { this.width = width; }
public void setHeight(double height) { this.height = height; }
public double getWidth() { return width; }
public double getHeight() { return height; }
public class Square extends Rectangle {
public void setWidth(double width){
super.setWidth(width);
super.setHeight(width);
}
public void setHeight(double height){
super.setWidth(height);
super.setHeight(height);
}
}
public void calArea(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
double area = r.getWidth() * r.getHeight();
if (area != 20)
System.out.println("Unexpected area: " + area);
}
What if
calArea()
is passed a
square?
SOLID PRINCIPLES
-
The Liskov Substitution Principle (LSP)
-
LSP is an important feature of programs that conform to the Open Closed
Principle
-
When subclasses are completely substitutable for their base class, then
methods that use the base class can be substituted with impunity and the
subclasses can be changed with impunity
-
In our example
-
Geometrically, a square is a rectangle, but a square object is not a rectangle
object.
-
Behaviorally, a square is not a rectangle. The behavior of a square object is
not consistent with the behavior of a rectangle object.
-
For LSP to hold, subclasses must conform to the behavior that clients expect of
the base classes that they use.
SOLID PRINCIPLES
-
The Interface Segregation Principle (ISP)
-
Using many client specific interfaces is better than using one general
purpose interface.
-
If you have a class that has several clients, rather than loading the
class with all the methods that the clients need, create specific
interfaces for each client.
-
It is okay for a method to appear in more than one interface so that
separate clients can use the same method.
-
When interfaces between classes and existing clients change, consider
adding new interfaces for existing objects which can reduce
recompilation and redeployment.
SOLID PRINCIPLES
-
The Interface Segregation Principle
(ISP)
-
Example for a design that does not
follow ISP
-
Bloated interfaces can lead to
inadvertent couplings between clients
Client A
Service
Client A methods
Client B
Client B methods
Client N
Client N methods
Video
<<interface>>
VideoActions
that ought to be isolated otherwise
-
Bloated interfaces can be segregated
to prevent this coupling
Prime Video
playVideo()
getVideoPlayTime()
playRandomAd()
SOLID PRINCIPLES
-
The Dependency Inversion Principle (DIP)
-
Depend on abstractions. Do not depend on concretions
(implementations)
-
High level modules should not depend on low level modules.
Both should depend upon abstractions.
-
Abstractions should not depend upon details. Details should
depend upon abstractions
-
Every dependency in a design should target an interface or an
abstract class. No dependency should target a concrete class
SOLID PRINCIPLES
-
The Dependency Inversion Principle (DIP)
-
the idea …
SOLID PRINCIPLES
-
The Dependency Inversion Principle (DIP)
-
Example for how a copy program can work with any reader and
writer that implement the Reader and Writer interfaces. It is
no longer dependent on particular lower level modules!
public void copy() throws Exception {
Scanner scnr = new Scanner(System.in);
PrintStream ps = new PrintStream(new File("myFile"));
while (scnr.hasNext()) {
String line = scnr.nextLine();
ps.println(line);
}
}
public interface Reader {
public boolean hasLine();
public String getLine() throws Exception;
}
public interface Writer {
public void putLine (String s) throws Exception;
}
public void copy( Reader input, Writer output) throws Exception{
while (input.hasLine()) {
output.putLine(input.getLine()));
}
}
SOLID PRINCIPLES
-
The Dependency Inversion Principle (DIP)
-
Proper application of the Dependency Inversion Principle is
necessary for the creation of reusable frameworks.
-
It is important for the construction of code that is resilient
to change.
-
When abstraction is isolated from details, code is easier to
maintain.
IMPORTANT
In the industry, problem
solving often requires
interaction among many
colleagues. Rarely will you
be able to get everyone on a
project to agree on the
right approach to a
solution. Also, rarely will
any particular approach be
perfect. You'll often
compare the relative merits
of different approaches.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,269 @@
Application
Programming
Hend Alkittawi
Android Development
Building a Multi-screen App
ROWDY QUIZ APP
-
We created the Rowdy Quiz app to read questions from a data
file and display them to the user.
-
We also added a logo to our screen
ROWDY QUIZ APP
-
We will modify the app to allow the user to peek at the answer
BUILDING A MULTI-SCREEN APP
-
To add a new screen to an Android app
1.
create a new activity and a new layout using the new activity
wizard
-
Right click on app > New > Activity > Empty Views Activity
-
this will create a new layout file and update the
AndroidManifest.xml file
-
the manifest is an xml file that contains metadata that describes
your application to the Android OS
-
every activity in an application must be declared in the manifest
so that the OS can access it
2.
add code to start the new activity
CREATING A NEW ACTIVITY
CREATING A NEW ACTIVITY
-
Create a new activity and a new layout using the new activity
wizard
-
The layout for the new screen has
-
LinearLayout
-
ImageView
-
TextView
-
TextView
-
Button
STARTING A NEW ACTIVITY
-
The simplest way to start another activity is with the
startActivity() method
Intent intent = new Intent(currentActivity, newActivity.class);
startActivity(intent)
-
For our app, MainActivity will start the PeekActivity in
response to a click on the Peek button
-
Add the following method to MainActivity.java and call it as
appropriate!
private void launchActivity() {
MainActivity
Intent intent = new Intent(this, PeekActivity.class);
}
startActivity(intent);
PeekActivity
STARTING A NEW ACTIVITY
-
Sometimes it is necessary to pass data between the starting
activity (parent) and the started activity (child).
-
When starting an activity, the starting (parent) activity can
add an extra to the intent with the putExtra() method
-
extras are arbitrary data that the calling activity can include
with an intent
-
an extra is a structured key-value pair
Intent intent = new Intent(currentActivity, newActivity.class);
intent.putExtra(name, value);
startActivity(intent)
STARTING A NEW ACTIVITY
-
Sometimes it is necessary to pass data between the starting
activity (parent) and the started activity (child)
-
to retrieve the extra from the intent use the get[type]Extra()
method
value = getIntent().get[type]Extra(name, default_val);
-
available methods
-
getBooleanExtra()
-
getCharExtra()
-
getIntExtra()
-
getStringExtra()
… etc.
STARTING A NEW ACTIVITY
-
For our app, MainActivity should pass the answer of the
current question to the PeekActivity so that the answer is
displayed to the user when the Show Answer button in is
clicked
// some code is omitted .. new code is highlighted here
// refer to full code on Github
// some code is omitted
// refer to full code on Github
public class MainActivity extends AppCompatActivity {
public class PeekActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_peek);
private static final String intentKey = "answer";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.show_answer_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String answer =
getIntent().getStringExtra(MainActivity.decodeIntent());
Button peekButton = findViewById(R.id.peek_button);
peekButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
launchActivity();
}
});
getIntent().getStringExtra(“answer”);
TextView answerTextView = findViewById(R.id.shown_answer);
answerTextView.setText(answer);
}
private void launchActivity() {
Intent intent = new Intent(this, PeekActivity.class);
intent.putExtra(intentKey, String.valueOf(getAnswer()));
startActivity(intent);
}
public static String decodeIntent(){
return intentKey;
}
}
}
});
}
}
BUILDING A MULTI-SCREEN APP
-
Rowdy Quiz Sequence Diagram
RowdyQuiz
Android OS
ActivityManager
MainActivity
User presses Peek
button, onClick()
called
Intent
startActivity(Intent)
component: PeekActivity
extra = answer
nt)
(inte
PeekActivity
User presses back
button
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,243 @@
Application
Programming
Hend Alkittawi
Debugging
How To Debug Java Code and Android
Applications
DEBUGGING ANDROID APPLICATIONS
-
Some of the problems you may
encounter while building android
applications. The application may
crash at runtime or not function as
expected!
-
As an IDE, Android Studio has some
tools to help developers debug their
code. These tools are:
-
The Logcat
-
Android Lint
-
The Debugger
THE LOGCAT
-
When an application is running, the Logcat tool window
provides access to diagnostic messages.
-
The log output displays messages which are created using the
Log class
-
The syntax to create a log diagnostic message is
Log.[logLevelInitial]("TAG", "Message")
-
Some of the available log levels:
-
Information, Verbose, Debug, Error
-
the log level and the tag helps with filtering messages
-
Example: Log.d("PeekActivity", "Button Clicked!")
THE LOGCAT
ANDROID LINT
-
Android Lint is a static analyzer for Android code
-
a program that examines your code to find defects without
running it
-
Android Lint is aware of the Android framework components and
and can find problems that the compiler cannot find.
-
For example, it is good for finding issues in XML files.
-
To run Android Lint: Code > Inspect Code the click Analyze
ANDROID LINT
THE DEBUGGER
-
The debugger is a tool mainly used to run the application under
controlled conditions that permit the developer to track its
execution and monitor changes in computer resources that may
indicate malfunctioning code.
-
To control the application execution, add breakpoints to your
code lines.
-
A breakpoint next to a line of code pauses the execution before
the line executes and allows you to examine what happens next.
-
To run the application in debug-mode, add breakpoint(s) then
Run > Debug
THE DEBUGGER
-
When using the debugger, the developer can control the app execution:
-
Step Into
-
A method is about to be invoked, and you want to debug into the code of that
method, so the next step is to go into that method and continue debugging
step-by-step.
-
Step Over
-
A method is about to be invoked, but you're not interested in debugging this
particular invocation, so you want the debugger to execute that method completely
as one entire step.
-
Step Return
-
You're done debugging this method step-by-step, and you just want the debugger to
run the entire method until it returns as one entire step.
-
Resume
-
You want the debugger to resume "normal" execution instead of step-by-step
p
THE DEBUGGER
1.
k
ea
r
b
g
2.
bu
e
D
nt
i
po
3. Control execution
Tra
ck
exe
cut
ion
ap
DEBUGGING ANDROID APPLICATIONS
-
When errors persist, some things you can try
-
Recheck the xml in resource files
-
Clean the project build
-
-
Build > Clean Project
-
Android studio will rebuild the project from scratch
Clean the project
-
File > Invalidate Caches/Restart
-
Android Studio will perform some maintenance on the project
and restart itself
-
Check online :)
CODE DEMO
-
Show the different
tools in Android
Studio.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,412 @@
Application
Programming
Hend Alkittawi
Exception Handling
Introduction To Java Errors And
Exceptions
INTRODUCTION
-
In Java when things go wrong a java.lang.Exception object is
created.
-
For example,
-
if we add elements to an uninitialized arraylist
-
-
if we try to read from a file that doesnt exist
-
-
FileNotFoundException
if we try to read past the end of the file
-
-
NullPointerException
IOException
if the file changes while we are reading it
-
IOException
THE CALL STACK
-
When a Java program runs, execution begins in the main()
method. The main() method creates objects and invokes methods
on them.
-
When execution moves to another method an entry is added to
the call stack.
-
When a method finishes executing, the entry
call stack
is removed from the call stack, and execution
returns to the next line in the main() method
-
obj.method()
this continues until the main method finishes
main()
THE CALL STACK
-
The call stack entry below, among other things, contains
-
the current method
-
where the call occurred in that method
NullPointerException:
at Student.getAverage(Student.java:79)
at Student.toString(Student.java:62)
at java.lang.String.valueOf(String.java:2615)
at java.io.PrintStream.print(PrintStream.java:616)
at java.io.PrintStream.println(PrintStream.java:753)
at Student.main(Student.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
EXCEPTIONS IN JAVA
-
In Java, all exception classes inherit from the Exception class
-
Exceptions in Java are checked or unchecked!
-
Checked exceptions must be caught or thrown. Examples of
checked exceptions include:
-
-
IOException
-
FileNotFoundException
Unchecked exceptions should never be caught or thrown. Examples
of unchecked exceptions include:
-
NullPointerException
-
ArrayIndexOutOfBoundsException
EXCEPTIONS IN JAVA
EXCEPTION HANDLING
-
As developers, we must address any problems that might occur.
-
For unchecked exceptions, your code should follow best
practices in order to prevent exceptions occurrences. For
example
-
-
check for array bounds
-
check for null values
For checked exceptions, your code either throws the exception
or handles the exception with a try/catch block.
EXCEPTION HANDLING
-
Using try, catch, and finally blocks
-
Wrap all code that can cause a checked exception in try, catch
(and optionally finally) blocks
try {
try {
System.out.println("code here can cause
an exception");
} catch (Exception e) {
System.out.println("reading from a file …");
} catch (FileNotFoundException e) {
System.out.println("handle exception here");
System.out.println("handle exception here");
} finally { // optional
} finally { // optional
System.out.println("code that must be absolutely
executed after try block completes");
}
System.out.println("closing the file …");
}
EXCEPTION HANDLING
-
A try block can have multiple catch blocks.
-
The order of the catch blocks is important.
try {
try {
System.out.println("reading from a file …");
} catch (FileNotFoundException e) {
System.out.println("reading from a file …");
} catch (IOException e) {
System.out.println("code here will execute
when a FileNotFoundException is thrown!");
} catch (IOException e) {
System.out.println("code here will execute
when a FileNotFoundException is thrown!");
} catch (FileNotFoundException e) {
System.out.println("handle exception here");
System.out.println("code here will not execute
when a FileNotFoundException is thrown!");
} finally {
} finally {
System.out.println("closing the file …");
}
System.out.println("closing the file …");
}
THROWING EXCEPTIONS
-
An exception might be thrown, when there is nothing more you
can do about it!
public void methodA() {
try {
dangerZone();
} catch (Exception e) {
e.printStackTrace();
}
}
public void dangerZone() throws Exception {
throw new Exception();
}
}
EXCEPTION HANDLING EXAMPLE
import java.io.FileNotFoundException;
public class DemoExceptions {
public static void main(String[] args) {
try {
method(true);
System.out.println("returned from method()");
} catch (FileNotFoundException e) {
System.out.println("caught the exception, will handle it!");
e.printStackTrace();
} finally {
// code that must be absolutely executed after try block completes
System.out.println("finally will cleanup!");
}
}
public static void method(boolean exception) throws FileNotFoundException {
if(exception)
throw new FileNotFoundException();
System.out.println("method 1 executed successfully!");
}
}
HANDLING EXCEPTIONS
-
Handling exceptions improves the user experience!
-
Consider
-
-
Where can errors happen caused by our logic?
-
Where can exceptions happen?
-
Where can user error occur?
For each, how can we prevent or reduce these?
-
What would the user expect?
USER EXPERIENCE!
-
Suppose you are
-
Suppose you are
-
Suppose you are
exploring with Google
searching Google (web
shopping on Amazon
earth (desktop app),
app), you enter some
(mobile app), you tap
you click a button and
text, click the button
a button and
it
and
-
-
Closes and/or
refreshes, losing
program/window
your search text
Changes the size of
-
The result page
The app closes (and
maybe reopens)
The web page
reopens the
-
The entire style of
the app changes
-
GUI components move
the window
comes up, without
around the view
Moves GUI
results
(unexpectedly)
components around
the view
-
-
-
Does nothing!
-
Nothing happens!
-
Nothing happens!
CODE DEMO
- Demo exception handling concepts
in Eclipse!
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,180 @@
Application
Programming
Hend Alkittawi
Leaderboard App
An App to Demo File IO, Exception
Handling, Scroll Views and Dynamic
Image Loading
ANDROID APP DEVELOPMENT
-
Roadmap
-
Gather requirements
-
Design views
-
-
Design model classes
-
-
(layout xml files - setup views ids)
(classes to represent app data)
Design controller
-
(classes to connect the views and model classes with methods
to handle user interactions and to manage the data flow and
update views)
-
Create your data files
ANDROID APP DEVELOPMENT
-
At this point we have most of the tools needed to create an
application.
-
To create an application, start by gathering requirements based on
which tasks and subtasks can be identified.
-
Important questions to ask
-
What is the main purpose of the application?
-
How will the user interact with it?
-
What technology will we use?
WRITING DATA TO A FILE
-
The Assets folder is read-only, we cannot write data to the files
in the Assets folder.
-
What if we need to modify data within a file located in the Assets
folder or create a file for both reading and writing data?
-
A work around this is to create a copy of the file from the Assets
to the AVD memory, then use the “copy file” for reading and writing
data.
-
To write data to a file, create a file in the AVD memory.
-
Once created, the file can be located in the AVD memory by
navigating to View > Tool Windows > Device Explorer then data >
user > 0 > edu.utsa.cs3443.projectName > files
SCROLL VIEWS
-
A ScrollView is a view group that allows the view hierarchy
placed within it to be scrolled.
-
A ScrollView may have only one direct child placed within it.
-
To add multiple views within the ScrollView, make the direct
child you add a view group, for example LinearLayout, and
place additional views within that LinearLayout.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
IMAGE VIEWS
-
An ImageView can display an image from the drawable folder
-
statically (hard-code)
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/rowdylogo"/>
-
dynamically (xml and controller class)
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/dynamic_image" />
public void displayImage(String filename){
ImageView dynamicImage = (ImageView) findViewById(R.id.dynamic_image);
int imageResource = getResources().getIdentifier(filename, "drawable", getPackageName());
dynamicImage.setImageResource(imageResource);
}
DYNAMIC LOADING OF VIEWS
-
MainActivity can dynamically place buttons in its layout
(screen)
private void dynamicSetupButton(String player){
// create a layout object
LinearLayout rootLayout = (LinearLayout) findViewById(R.id.root_layout);
Button myButton = new Button(this);
myButton.setText(player);
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { Log.i(TAG, "Clicked on " + myButton.getText()); }
});
// setup the attributes for the button
LinearLayout.LayoutParams buttonAttributes
= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
// add the button to the layout
rootLayout.addView(myButton, buttonAttributes);
}
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,364 @@
Application
Programming
Hend Alkittawi
Java Generics
Working With Generic Data Types
INTRODUCTION
-
An arraylist of Strings can be created with generics, as in
ArrayList<String> list = new ArrayList<String>();
list.add("hello"); // Add a String object to the list
-
In order to retrieve a String object from the list, we do not
need to cast it to a String type
String s = list.get(0);
-
When an arraylist of String objects is created with generics,
the following statements are not valid statements
// Adding an Integer to the String list produces a compilation error
list.add(0);
INTRODUCTION
-
An arraylist of Strings can be created without generics, as in
ArrayList list = new ArrayList();
list.add("hello"); // Add a String object to the list
-
In order to retrieve a String object from the list, we must
cast it to a String type
String s = (String) list.get(0);
-
When an arraylist of String objects is created without
generics, the following statements are valid statements
list.add(0);
// Add an Integer to the list
Integer s = (Integer) list.get(1);
JAVA GENERICS
-
In a nutshell, generics enable types (classes and interfaces) to
be parameters when defining classes, interfaces and methods
-
Advantages to using generics in your code
-
Enables programmers to implement generic algorithms
-
focus is on creating more elegant algorithms, rather than syntax
-
still generates clean, type-safe, customizable code
-
Eliminates casting
-
Stronger type checks are performed at compile time
-
if a problem exists, its better to find it at compile time than at
run time!
GENERIC METHODS
-
Creating generic methods enables code reuse and simplifies your code.
-
For example:
-
A method which takes in an array of numbers, and returns a random element in the
array:
public Integer getRandomElement(Integer[] array) {
Random random = new Random();
int index = random.nextInt(array.length);
Integer result = array[index];
return result;
}
-
A method which takes in an array of Strings, and returns a random element in the
array:
public String getRandomElement(String[] array) {
Random random = new Random();
int index = random.nextInt(array.length);
String result = array[index];
return result;
}
GENERIC METHODS
-
From the previous example, a generic method that enables code
reuse and simplifies the code can be created
public <T> T getRandomElement(T[] array) {
Random random = new Random();
int index = random.nextInt(array.length);
T result = array[index];
return result;
}
-
<T> indicates that the method will be a generic method
-
T indicates the type of the generic variable in the method
-
defined when the method is called!
GENERIC METHODS
-
A generic method that enables code reuse and simplifies your
code!
public <T> T getRandomElement(T[] array) {
Random random = new Random();
int index = random.nextInt(array.length);
T result = array[index];
return result;
}
-
We can call this method as follows
Integer[] intArray = { 1, 3, 5, 7, 9, 0, 2, 4, 6, 8 };
String[] stringArray = { "xx", "yy", "zz", "aa", "bb", "cc" };
Integer rint = getRandomElement(intArray);
String rstring = getRandomElement(stringArray);
GENERIC CLASSES
-
A generic class is a class that is parameterized over types.
-
One of the key concepts of Java generics is that only the
compiler processes the generic parameters.
-
The Java compiler uses generics to ensure type-safety.
-
There is no generic type-checking in the runtime code.
-
Essentially, generic classes avoid the same issues faced in
our previous example for generic methods.
-
Think about a generic Stack class!
/**
* A PairOfIntegers object stores a pair
* of Integers.
*
* @author Tom Bylander
*/
public class PairOfIntegers {
/**
* A PairOfStrings object stores a pair
of strings.
*
* @author Tom Bylander
*/
public class PairOfStrings {
private Integer first, second;
private String first, second;
public PairOfIntegers(Integer
integer1, Integer integer2){
first = integer1;
second = integer2;
}
public PairOfStrings(String string1,
String string2){
first = string1;
second = string2;
}
public Integer getFirst() {
return first;
}
public String getFirst() {
return first;
}
public Integer getSecond() {
return second;
}
public String getSecond() {
return second;
}
}
/**
* A PairOfIntegerAndDouble object stores
an Integer and a Double.
*
* @author Tom Bylander
*/
public class PairOfIntegerAndDouble {
private Integer first;
private Double second;
public PairOfIntegerAndDouble(
Integer first, Double second){
this.first = first;
this.second = second;
}
public Integer getFirst() {
return first;
}
public Double getSecond() {
return second;
}
}
}
/**
* A PairOfObjects object stores a pair
* of objects.
*
* @author Tom Bylander
*/
/**
* A PairOfSameType object stores a pair * of
objects generic type T.
* T is specified when
* declaring the PairOfSameType variable.
*
* @author Tom Bylander
*/
public class PairOfObjects {
public class PairOfSameType<T> {
// Note the use of the generic
// parameter T.
private T first, second;
Private ArrayList<T> myList;
private Object first, second;
public PairOfObjects(Object object1,
Object object2){
first = object1;
second = object2;
}
/**
* A PairOfDifferentTypes object stores a *
pair of objects.
* The type parameter S is for the first *
object.
* The type parameter T is for the second *
object.
* @author Tom Bylander
*/
public class PairOfDifferentTypes<S,T> {
// Note the use of S and T.
private S first;
private T second;
public PairOfDifferentTypes(
S object1, T object2){
first = object1;
second = object2;
}
public PairOfSameType(T object1,
T object2){
first = object1;
second = object2;
}
public Object getFirst() {
return first;
}
public S getFirst() {
return first;
}
public T getFirst() {
return first;
}
public Object getSecond() {
return second;
}
public T getSecond() {
return second;
}
}
public T getSecond() {
return second;
}
}
}
PairOfObjects pair7 =
new PairOfObjects(123, 0.456);
PairOfSameType<Integer> pair5 =
new PairOfSameType<Integer>(123,456);
PairOfDifferentTypes<Integer,Double> pair9 =
new PairOfDifferentTypes<Integer,Double>
(123, 0.456);
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,407 @@
Application
Programming
Hend Alkittawi
03
Java Collections
Collections are Javas Data
Structures
JAVA COLLECTIONS
-
In Java, Collection is an interface. It is the root interface in
the collection hierarchy. A collection represents a group of
objects, known as its elements.
-
Some collections allow duplicate elements and others do not.
Some are ordered and others unordered.
-
The java.util package contains many Java collections, a few of
the most common are
-
List
-
Set
-
Map
JAVA COLLECTIONS
-
The Collection interface defines the behaviors of a collection,
including typical operations such as
-
add elements to the collection
.add()
-
access elements of the collection
.get()
-
loop over the elements in the collection
iterator
-
access an element by its index, if applicable
iterator
-
test whether an element is contained in the collection
.contains()
-
find out the size of the collection
.size()
-
remove elements from the collection
.remove()
JAVA COLLECTIONS HISTORY
-
JDK 1.0: Vector, Dictionary, Hashtable, Stack, Enumeration
-
JDK 1.2: Collection, Iterator, List, Set, Map, ArrayList,
HashSet, TreeSet, HashMap, WeakHashMap
-
JDK 1.4: RandomAccess, IdentityHashMap, LinkedHashMap,
LinkedHashSet
-
JDK 1.5: Queue, …
-
JDK 1.6: Deque, ConcurrentSkipListSet/Map, …
-
JDK 1.7: TransferQueue, LinkedTransferQueue
JAVA COLLECTIONS AND GENERICS
-
Leveraging generics when initializing a collection is a common
practice.
-
Typically, a collection is declared by including the type of
elements it contains within <...>, which is using Java's
generics notation.
-
For example
// declare list to be a collection of Strings
Collection<String> list;
// initialize list to a concrete class that implements Collection
list = new ArrayList<String>();
JAVA LISTS
-
The List interface represents an ordered collection (also
known as a sequence).
-
Some of the classes that implement the List interface are
-
ArrayList which is a resizable-array implementation of the
List interface.
-
LinkedList which is a doubly-linked list implementation of the
List and Deque interfaces.
JAVA LISTS
-
An example for using a LinkedList
List<String> colorList = new LinkedList<String>();
colorList.add("red");
colorList.add("yellow");
colorList.add("blue");
JAVA SETS
-
The Set interface represents a collection that contains no
duplicate elements.
-
Some of the classes that implement the List interface are
-
HashSet
-
TreeSet
JAVA SETS
-
An example for using a HashSet
String[] colors = {"red","white","blue","green","gray","orange","tan","white","cyan","peach","gray","orange"};
List<String> list = Arrays.asList(colors);
System.out.printf("List: %s%n", list);
prints …
This Arrays class contains various methods for
manipulating arrays (such as sorting and searching).
This class also contains a static factory that allows
arrays to be viewed as lists.
List: [red, white, blue, green, gray, orange, tan, white, cyan, peach, gray, orange]
String[] colors = {"red","white","blue","green","gray","orange","tan","white","cyan","peach","gray","orange"};
List<String> list = Arrays.asList(colors);
Set<String> set = new HashSet<String>(list);
System.out.printf("Set: %s%n", set);
prints …
Set: [tan, green, peach, cyan, red, orange, gray, white, blue]
JAVA MAPS
-
The Map interface represents an object that maps keys to values. A
map cannot contain duplicate keys; each key can map to at most one
value.
-
Some of the classes that implement the List interface are
-
HashMap
-
TreeMap
JAVA MAPS
-
An example for using a HashMap
// Not using maps, maintain two arrays, one for names and one for IDs
String[] studentNames = {"Alice", "Bob", "Carlos", "Diane"};
String[] studentIDs = {"atf123", "ght456", "liw789", "pwt012"};
// then to print out Alice, we need to know she is at index 0
System.out.println( studentIDs[0] );
// Instead, use a map!
Map<String,String> classMap = new HashMap<String,String>();
classMap.put("atf123", "Alice");
//As students register for the class,
classMap.put("ght456", "Bob");
// you can add them to the map. Then to
classMap.put("liw789", "Carlos");
// retrieve them, you only need their ID.
classMap.put("pwt012", "Diane");
System.out.println( classMap.get("atf123") );
JAVA MAPS
-
Another example for using a HashMap
// Phone book implementation
Map<String,PhoneNumber> phoneBook = new HashMap<String,PhoneNumber>();
phoneBook.put("Alice", new PhoneNumber("210-555-1234"));
phoneBook.put("Bob", new PhoneNumber("210-555-4321"));
phoneBook.put("Carlos", new PhoneNumber("210-555-4444"));
phoneBook.put("Diane", new PhoneNumber("210-555-1111"));
System.out.println( phoneBook );
public class PhoneNumber{
private String number;
public PhoneNumber( String phoneNumber ){
this.number = phoneNumber;
}
prints …
}
@Override
public String toString() {
return "PhoneNumber [number=" + number + "]";
}
{Bob=PhoneNumber [number=210-555-4321], Alice=PhoneNumber [number=210-555-1234], Diane=PhoneNumber [number=210-555-1111],
Carlos=PhoneNumber [number=210-555-4444]}
JAVA MAPS
-
Another example for using a HashMap
Map<String, ArrayList<String>> states = new HashMap<String,ArrayList<String>>();
ArrayList<String> tx = new ArrayList<String>();
tx.add( "San Antonio" );
tx.addAll( Arrays.asList("Austin", "Dallas", "Corpus Christi", "El Paso") );
states.put("Texas", tx );
ArrayList<String> ny = new ArrayList<String>();
ny.addAll( Arrays.asList("NYC", "Albany", "Niagara", "Long Island") );
states.put("New York", ny );
System.out.println( states );
prints …
{New York=[NYC, Albany, Niagara, Long Island], Texas=[San Antonio, Austin, Dallas, Corpus Christi, El Paso]}
CLASS ACTIVITY
-
What collection types would you use in the following examples?
-
A phone book (name, phone number)
-
Storing user interaction history (clicks, actions, choices, etc)
-
An address book (name, phone number, address, etc)
-
User choices for character attributes in a game (hair color, shoes,
etc)
-
Ordered task manager
CLASS ACTIVITY
-
What collection types would you use in the following examples?
-
A phone book (name, phone number)
-
-
Storing user interaction history (clicks, actions, choices, etc)
-
-
List
An address book (name, phone number, address, etc)
-
-
Map
Map
User choices for character attributes in a game (hair color, shoes,
etc)
-
-
Set
Ordered task manager
-
List
CLASS ACTIVITY
-
Come up with 3 distinct applications that
-
Require a List
-
Require a Set
-
Require a Map
CLASS ACTIVITY
-
Come up with 3 distinct applications that
-
Require a List
-
Groceries list/High scores/List of images/To do
list/Assignments/Labs
-
Require a Set
-
Enrollment UTSA/Census/UTSA IDs/Grocery list!/Medical
files/Word count
-
Require a Map
-
Login info/UTSA schedule/Dictionary/Word count/parking spots
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,309 @@
Application
Programming
Hend Alkittawi
Java Iteration
Iterating through objects in Java
Collections
INTRODUCTION
-
Related to the discussion on Java generics and collections is the
discussion on the following interfaces
-
-
Iterator, Iterable, Comparable, Comparator
The Java API has a consistent approach to iterators that are
implemented by nearly all collections in the class Library.
-
Iterators are implemented in the Java API using two primary interfaces:
-
Iterator: used to define an object that can be used as an iterator.
-
Iterable: used to define a collection from which an iterator can be
extracted.
-
The Comparable and Comparator interfaces in Java facilitate comparisons
between objects
THE ITERATOR INTERFACE
-
The Iterator interface is defined in the Java APIs.
-
The interface is used by a class that represents a collection
of objects, providing a means to move through the collection
one object at a time.
-
An Iterator provides a consistent and simple mechanism for
systematically processing a group of objects.
-
An Iterator is an object that has methods that allow you to
process a collection of items one at a time.
-
An Iterator object in Java is defined using the Iterator
interface.
THE ITERATOR INTERFACE
-
Every iterator object has a method called hasNext() that
returns a boolean value indicating whether there is at least
one more item to process.
-
Every Iterator also has a method called next() to retrieve the
next item in the collection to process.
-
The Iterator interface also has a method called remove() which
takes no parameters and has a void return type. A call to the
remove() method removes the object that was most recently
returned by the next method from the underlying collection.
THE ITERABLE INTERFACE
-
The Iterable interface has a single method iterator() that returns an Iterator
object.
-
If an object has implemented the Iterable interface, we can use a variation of the
for loop to process items using a simplified syntax → The enhanced for loop
(for-each loop).
-
For example if bookList is an Iterable object that contains book objects we can use
a for loop to process each book object as follows
for (Book myBook: bookList)
system.out.println( myBook)
-
This version of the for Loop processes each object in the Iterator in turn. It is
equivalent to the following:
Book myBook;
while( bookList.hasNext(){
myBook = bookList.next();
System.out.println( myBook) }
import java.util.Iterator;
public class Range implements
Iterable<Integer>{
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Iterator;
public class RangeTest {
public class RangeIterator implements
Iterator<Integer>{
public static void main(String[] args){
Range range = new Range(1, 7);
System.out.println("Looping with an
iterator");
Iterator<Integer> it =
range.iterator();
while(it.hasNext()){
int cur = it.next();
System.out.print(cur + "\t");
}
private int start, end;
private int cursor;
private int end;
public Range(int start, int end) {
this.start = start;
this.end = end;
}
public RangeIterator(int start, int
end){
this.cursor = start;
this.end = end;
}
public Iterator<Integer> iterator(){
return new RangeIterator(start,
end);
}
public boolean hasNext() {
return this.cursor < end;
}
}
public Integer next() {
if(this.hasNext()) {
int current = cursor;
cursor++;
return current;
}
throw new NoSuchElementException();
}
public void remove() {
throw new
UnsupportedOperationException();
}
}
System.out.println("\nLooping with a
for-each loop");
for(Integer cur : range){
System.out.print(cur + "\t");
}
}
}
Looping with an iterator
1
2
3
4
5
Looping with a for-each loop
1
2
3
4
5
6
6
public class Course {
private String prefix;
private int number;
private String title;
private String grade;
public class ProgramOfStudy implements
Iterable<Course>{
private List<Course> list;
public ProgramOfStudy(){
list = new LinkedList<Course>();
}
public Course(String prefix, int number,
String title, String grade){
this.prefix = prefix;
this.number = number;
this.title = title;
if (grade == null)
this.grade = "";
else
this.grade = grade;
}
public Course(String prefix, int number,
String title){
this(prefix, number, title, "");
}
public class IterableTest {
public static void main(String[] args) throws
Exception{
ProgramOfStudy pos = new ProgramOfStudy();
pos.loadCourses();
System.out.println(pos);
public void addCourse(Course course){
if (course != null)
list.add(course);
}
for(Course course : pos) {
pos.addCourse(new Course("MATH", 1044,
"Caluclus I"));
}
public String toString(){
String result = "";
for (Course course : list)
result += course + "\n";
return result;
}
System.out.println("Removing courses with
no grades.\n");
Iterator<Course> itr = pos.iterator();
while (itr.hasNext()){
Course course = itr.next();
if (!course.taken())
itr.remove();
}
System.out.println(pos);
}
@Override
public Iterator<Course> iterator() {
return list.iterator();
}
public boolean taken(){
return !grade.equals("");
}
public void loadCourses() {
list.add(new Course("CS", 3443,
"Application Programming", "A+"));
list.add(new Course("CS", 3343,
"Algorithms", "B"));
list.add(new Course("CS", 1173, "Data
Analysis and Visualization", "C+"));
list.add(new Course("CS", 2073,
"Introduction to Programming"));
}
public String toString(){
String result = prefix + " " + number
+ ": " + title;
if (!grade.equals(""))
result += " [" + grade + "]";
return result;
}
}
}
}
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,396 @@
Application
Programming
Hend Alkittawi
Java Comparison
Comparing objects in Java
Collections
INTRODUCTION
-
Related to the discussion on Java generics and collections is the
discussion on the following interfaces
-
-
Iterator, Iterable, Comparable, Comparator
The Java API has a consistent approach to iterators that are
implemented by nearly all collections in the class Library.
-
Iterators are implemented in the Java API using two primary interfaces:
-
Iterator: used to define an object that can be used as an iterator.
-
Iterable: used to define a collection from which an iterator can be
extracted.
-
The Comparable and Comparator interfaces in Java facilitate comparisons
between objects
COMPARING OBJECTS
-
Classes that implement the Comparable and Comparator
interfaces must contain certain key methods for comparing
objects created by that class
-
For example, the String class implements Comparable, so
sorting Strings in an array alphabetically is easy
String[] fruits = new String[] {"Pineapple", "Apple", "Orange", "Banana"};
Arrays.sort(fruits);
THE COMPARABLE INTERFACE
-
The Comparable interface contains only one method: compareTo()
which takes an object as a parameter and returns an integer
-
The purpose of this interface is to provide a common mechanism for
comparing one object to another
ClassName obj1 = new ClassName();
ClassName obj2 = new ClassName();
int result
= obj1.compareTo(obj2);
-
The integer that is returned from the compareTo() method should be
-
negative if obj1 < obj2
-
positive
if obj1 > obj2
-
zero
if obj1 = obj2
THE COMPARABLE INTERFACE
-
If an object is Comparable, we can sort an array of it
Book book1 = new Book(...);
Book book2 = new Book(...);
-
For an array of Comparable objects, use
Arrays.sort()
The Arrays class provides the sorting logic for Comparable types
-
Arrays.sort()takes an array of objects which implement the
Comparable interface
Book[] books = new Book[2];
books[0] = book1;
books[1] = book2;
Arrays.sort( books );
// Comparable
THE COMPARABLE INTERFACE
-
If an object is Comparable, we can sort a collection of it
Book book1 = new Book(...);
Book book2 = new Book(...);
-
For an arraylist of Comparable objects use the sort() method
from Collections
ArrayList<Book> bookList = new ArrayList<Book>();
bookList.add( book1 );
bookList.add( book2 );
Collections.sort( bookList );
// some code is omitted, check code for
project in Canvas
public class ComparableTest {
public static void main(String[] args) {
Book book1 = new Book("Java The Complete Guide", "Pat Alfonso");
Book book2 = new Book("Java for Begginers",
"Hamza Ryan");
Book book3 = new Book("Java for Begginers",
"Daisy Mack");
Book book4 = new Book("Java All in One",
"Carolina Minato");
Book book5 = new Book("Java All in One",
"Carolina Aidan");
public class Book implements Comparable<Book> {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
ArrayList<Book> bookArrayList = new ArrayList<Book>();
bookArrayList.addAll(Arrays.asList(book1, book2, book3, book4, book5));
System.out.println("******* Unsorted Collection *******");
System.out.println(bookArrayList);
@Override
public String toString() {
return "Book [title=" + title + ", author="
+ author + "]";
}
@Override
public int compareTo(Book other) {
return
this.getAuthor().compareTo(
Collections.sort(bookArrayList);
System.out.println("******* Sorted Collection *******");
System.out.println(bookArrayList);
Book[] bookArray = {book1, book2, book3, book4, book5};
System.out.println("******* Unsorted Array *******");
for(Book book : bookArray)
System.out.println(book);
other.getAuthor());
}
}
Arrays.sort(bookArray);
System.out.println("******* Sorted Array *******");
for(Book book : bookArray)
System.out.println(book);
}
}
THE COMPARATOR INTERFACE
-
The Comparator interface contains the compare() method which takes two
objects as a parameter and returns an integer
-
If an object is Comparator, we can sort an array of it
Book book1 = new Book(...);
Book book2 = new Book(...);
-
For an array of Comparable objects, use
Arrays.sort()
The Arrays class provides the sorting logic for Comparable types
-
Arrays.sort()takes an array of objects which implement the Comparable
interface
Book[] books = new Book[2];
books[0] = book1;
books[1] = book2;
Arrays.sort( books );
// Comparable
Arrays.sort( books, Book.bookComparator ); // Comparator
THE COMPARATOR INTERFACE
-
For an arrayList, you can use the use the sort() method from ArrayList
bookList.sort( Book.bookComparator );
where BookComparator is defined in the Book class as follows
public static Comparator<Book> bookComparator
= new Comparator<Book>() {
public int compare(Book book1, Book book2) {
return book1.getTitle().compareTo(book2.getTitle());
}
};
// public static Comparator<Book> bookComparator = new Comparator<Book>();
-
Inner classes are classes defined within another class.
-
An anonymous inner class is a class without a name, for which only one object is
created.
Implementing The Comparator Interface
public static MyComparator bookComparator;
public class MyComparator implements Comparator<Book>{
@Override
public int compare(Book book1, Book book2){
return book1.getAuthor().compareTo(book2.getAuthor());
}
}
private String title;
private String author;
// some code is omitted, check code for project in Canvas
// some code is omitted, check code
for project in Canvas
public class Book {
public class ComparatorTest {
public Book(String title, String author){
this.title = title;
this.author = author;
bookComparator = new MyComparator();
}
public static void main(String[] args){
Book book1 = new Book("Java The Complete Guide", "Pat Alfonso");
Book book2 = new Book("Java for Begginers",
"Hamza Ryan");
Book book3 = new Book("Java for Begginers",
"Daisy Mack");
Book book4 = new Book("Java All in One",
"Carolina Minato");
Book book5 = new Book("Java All in One",
"Carolina Aidan");
@Override
public String toString() {
return "Book [title=" + title + ",
author=" + author + "]";
}
ArrayList<Book> bookArrayList = new ArrayList<Book>();
bookArrayList.addAll(Arrays.asList(book1, book2, book3, book4, book5));
Collections.sort(bookArrayList, Book.bookComparator);
}
// OR
bookArrayList.sort(Book.bookComparator);
}
Implementing The Comparator Interface As An Inner Class
// some code is omitted, check code for project
in Canvas
// some code is omitted, check code for project in Canvas
public class ComparatorTest {
public class Book {
public static MyComparator bookComparator;
private String title;
private String author;
public static void main(String[] args){
Book book1 = new Book("Java The Complete Guide", "Pat Alfonso");
Book book2 = new Book("Java for Begginers",
"Hamza Ryan");
Book book3 = new Book("Java for Begginers",
"Daisy Mack");
Book book4 = new Book("Java All in One",
"Carolina Minato");
Book book5 = new Book("Java All in One",
"Carolina Aidan");
public Book(String title, String author) {
this.title = title;
this.author = author;
bookComparator = new MyComparator();
}
@Override
public String toString() {
return "Book [title=" + title
+ ", author=" + author + "]";
}
private class MyComparator implements Comparator<Book> {
@Override
public int compare(Book book1, Book book2) {
return book1.getAuthor().
compareTo(book2.getAuthor());
}
}
}
ArrayList<Book> bookArrayList = new ArrayList<Book>();
bookArrayList.addAll(Arrays.asList(book1, book2, book3, book4, book5));
Collections.sort(bookArrayList, Book.bookComparator);
// OR
bookArrayList.sort(Book.bookComparator);
}
Implementing The Comparator Interface As An Anonymous
Inner Class
// some code is omitted, check code for project
in Canvas
public class Book {
public static MyComparator bookComparator;
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
bookComparator = new MyComparator();
}
@Override
public String toString() {
return "Book [title=" + title
+ ", author=" + author + "]";
}
private class MyComparator implements Comparator<Book> {
@Override
public int compare(Book book1, Book book2) {
return book1.getAuthor().
compareTo(book2.getAuthor());
}
}
}
// some code is omitted, check code for project in Canvas
public class Book {
public static Comparator<Book> bookComparator = new Comparator<Book>() {
public int compare(Book book1, Book book2) {
return book1.getAuthor().compareTo(book2.getAuthor());
}
};
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
}
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,633 @@
Application
Programming
Hend Alkittawi
Lambda Expressions
Introduction to Lambda Expressions
in Java
INTRODUCTION
-
To understand Javas implementation of lambda expressions we
need to understand what Functional Interfaces and a Lambda
Expressions are!
-
A Functional Interface is an interface that contains one and
only one abstract method
-
A Lambda Expression is an anonymous (unnamed) method, used to
implement a method defined by a functional interface
-
A functional interface defines a target type of a lambda
expression!
LAMBDA EXPRESSIONS FUNDAMENTALS
-
Lambda expressions use the lambda operator (->)
-
left-side: specifies any parameters requires by the lambda expression
-
right-side: the lambda body which specifies the actions of the lambda
expression
(parameters) -> (body)
-
Lambda body can be
-
-
single expression
-
() -> (123.45)
-
() -> (Math.random() * 100)
-
(n) -> ( (n%2) == 0 )
block of code
-
(n) -> {
for(int i = 0; i < n; i++)
System.out.println(i); }
LAMBDA EXPRESSIONS FUNDAMENTALS
-
A lambda expression is not executed on its own; it forms the
implementation of the abstract method defined by the functional
interface that specifies its target type!
-
The lambda expression can be specified only in a context in
which a target type is specified.
-
one of these contexts is created when a lambda expression is
assigned to a functional interface reference.
FunctionalInterface var = (parameters) -> (body);
LAMBDA EXPRESSIONS SINGLE EXPRESSION
-
An instance of a class is
automatically created that implements
the functional interface, with the
lambda expression defining the
behavior of the abstract method
declared by the functional interface.
-
public interface MyNumber {
public double getValue();
}
public class MyFirstNumber implements MyNumber{
@Override
public double getValue() {
return 100;}
}
public class MySecondNumber implements MyNumber{
@Override
public double getValue() {
return Math.random() * 100; }
}
public class LambdaDemo {
public static void main(String[] args) {
When that method is called through
MyFirstNumber first = new MyFirstNumber();
double m = first.getValue();
the target, the lambda expression is
MySecondNumber second = new MySecondNumber();
double n = second.getValue();
executed
-
The lambda expression gives us a way
MyNumber x = () -> 100;
MyNumber y = () -> Math.random() * 100;
to transform a code segment into an
System.out.println("m: " + m + " n: " + n +
" x: " + x.getValue() + " y: " + y.getValue());
// MyNumber z = () -> "123.5";
object!
}
LAMBDA EXPRESSIONS - SINGLE EXPRESSION
-
The type of the parameter
(n) is not specified; it is
public interface NumericTest {
public boolean test(int n);
}
inferred from the context.
-
-
The parameter type of test()
public class LambdaDemo {
public static void main(String[] args) {
It is possible to explicitly
NumericTest isEven = (n) -> (n % 2) == 0;
System.out.println(isEven.test(5));
System.out.println(isEven.test(6));
specify the type of the
NumericTest isPositive = (n) -> (n > 0);
parameter in a lambda
expression
-
( int n ) -> ( n % 2) == 0
System.out.println(isPositive.test(-1));
System.out.println(isPositive.test(1));
}
}
LAMBDA EXPRESSIONS - CODE BLOCK
-
A block lambda encloses the body within braces { }
-
The block body of a lambda is similar to a method body
public interface NumericFunction {
public int func(int n);
}
public class LambdaDemo {
public static void main(String[] args) {
NumericFunction factorial = (n) -> { int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
};
System.out.println(factorial.func(5));
public interface StringFunction {
public String func(String n);
}
StringFunction reverse = (str) -> { String result = "";
for (int i = str.length() - 1; i >= 0; i--) {
result = result + str.charAt(i);
}
return result;
};
System.out.println(reverse.func("Lambda"));
}
}
LAMBDA EXPRESSIONS FUNDAMENTALS
-
The functional interface associated with a lambda
expression can be generic.
public interface NumericFunction {
public int func(int n);
}
public class LambdaDemo {
public static void main(String[] args) {
SomeFunction<Integer> factorial = (n) -> { int result = 1;
for (int i = 1; i <= n; i++){
result = result * i;
}
return result;
};
System.out.println(factorial.func(5));
public interface StringFunction {
public String func(String n);
}
SomeFunction<String> reverse = (str) -> { String result = "";
for (int i = str.length() - 1; i >= 0; i--){
result = result + str.charAt(i);
}
return result;
};
System.out.println(reverse.func("Lambda"));
public interface SomeFunction<T> {
public T func(T t);
}
}
}
LAMBDA EXPRESSION FUNDAMENTALS
-
A lambda expression can be
passed as an argument to a
method.
-
A very powerful use of lambda
public interface StringFunction {
public String func(String n);
}
public class LambdaDemo {
expressions which gives you a
-
public static void main(String[] args) {
way to pass executable code as
String inStr = "Lambdas Add Power To Java!";
an argument to a method
StringFunction capitalize = (str) -> str.toUpperCase();
String outStr1 = stringOp(capitalize, inStr);
The type of the parameter
String outStr2 = stringOp( (str) -> str.toLowerCase(), inStr);
System.out.println("inStr: " + inStr
+ " outStr1: " + outStr1
+ " outStr2: " + outStr2);
receiving the lambda
}
expression must be of a
public static String stringOp(StringFunction sf, String s) {
return sf.func(s);
}
functional interface
compatible with the lambda
}
PREDEFINED FUNCTIONAL INTERFACES
-
The previous examples have defined their own functional
interfaces.
-
In many cases, there is no need to define your own functional
interface; Javas java.util.function package provides several
predefined functional interfaces!
Interface
Method
Parameter(s)
Returns
Function<T,R>
apply
T
R
Predicate<T>
test
T
boolean
UnaryOperator<T>
apply
T
T
BinaryOperator<T>
apply
T, T
T
FUNCTION<T, R> INTERFACE
-
The Function interface requires a parameter type and a return
type.
-
Interface
Method
Parameter(s)
Returns
Function<T,R>
apply
T
R
public interface Function<T, R> {
public R apply(T t);
}
A usage example …
Function<Integer,Double> getHalf = (x) -> (x / 2.0);
double result = getHalf.apply( 5 );
PREDEFINED FUNCTIONAL INTERFACES - EXAMPLE
public interface NumericFunction {
public int func(int n);
}
public class LambdaDemo {
public static void main(String[] args) {
NumericFunction factorial = (n) -> { int result = 1;
for (int i = 1; i <= n; i++)
result = result * i;
return result;
};
System.out.println(factorial.func(5));
}
}
Interface
Method
Parameter(s)
Returns
Function<T,R>
apply
T
R
public interface Function<T, R> {
public R apply(T t);
}
public class LambdaDemo {
public static void main(String[] args) {
Function<Integer, Integer> factorial = (n) -> { int result = 1;
for (int i = 1; i <= n; i++)
result = result * i;
return result;
};
System.out.println(factorial.apply(5));
}
}
PREDICATE<T> INTERFACE
-
The Predicate interface requires a parameter type and returns
a boolean.
-
Interface
Method
Parameter(s)
Returns
Predicate<T>
test
T
boolean
public interface Predicate<T> {
public boolean test(T t);
}
A usage example …
Predicate<Double> checkPassing =(grade)->(grade >= 60);
boolean isPassing = checkPassing.test( 68.5 );
UNARY OPERATOR
-
The UnaryOperator interface requires a parameter type and
returns a value of the same type
-
Interface
Method
Parameter(s)
Returns
UnaryOperator<T>
apply
T
T
public interface UnaryOperator<T> {
public T apply(T t);
}
An usage example …
UnaryOperator<Integer> uSquare = (i) -> (i*i);
int result = uSquare.apply( 3 );
BINARY OPERATOR
-
The BinaryOperator interface requires a parameter type and
returns a value of the same type.
-
Interface
Method
Parameter(s)
Returns
BinaryOperator<T>
apply
T, T
T
public interface BinaryOperator<T> {
public T apply(T t1, T t2);
}
A usage example
BinaryOperator<Integer> bMult = (a, b)-> (a * b);
int result = bMult.apply( 5, 2 );
LAMBDA EXPRESSIONS AND ANONYMOUS INNER CLASSES
-
Inner classes are classes defined within another class.
-
An anonymous inner class is a class without a name, for which
only one object is created!
public static Comparator<Book> bookComparator = new Comparator<Book>() {
public int compare(Book book1, Book book2) {
return book1.getTitle().compareTo(book2.getTitle());
}
};
-
A lambda expression can be utilized instead of an anonymous
inner class
public static Comparator<Book> bookComparator = (book1, book2) -> {
return book1.getTitle().compareTo(book2.getTitle());
};
LAMBDA EXPRESSIONS AND ANONYMOUS INNER CLASSES
-
In Android, recall that the setOnClickListener() method takes a
listener as its argument. It takes an object that implements
View.OnClickListener.
-
The listener can be implemented as an anonymous inner class, which
puts the implementation of the listeners methods right where you
want to see them.
-
The syntax can be simplified by using lambda expressions!
LAMBDA EXPRESSIONS AND ANONYMOUS INNER CLASSES
-
The listener can be implemented as an anonymous inner class
Button button = (Button) findViewById(R.id.my_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView myTextView = (TextView) findViewById(R.id.my_textview);
myTextView.setText("Salam!");
}
});
-
The syntax can be simplified by using lambda
expressions!
Button button = (Button) findViewById(R.id.my_button);
button.setOnClickListener((view) -> {
TextView myTextView = (TextView) findViewById(R.id.my_textview);
myTextView.setText("Salam!");
});
my_
tex
my_
but
tvi
ton
ew
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,618 @@
Application
Programming
Hend Alkittawi
Threads & Concurrency
Introduction to Java Threads and
Synchronization
INTRODUCTION
-
All modern operating systems support concurrency, via
processes and threads.
-
A process is an instance of a program running in a computer
-
example: if you start a java program, the OS spawns a new
process, which runs in parallel to other programs.
-
A thread is a program unit that is executed concurrently with
other parts of the program.
-
One or more threads run in the context of the process.
-
Multiple threads can collaborate and work efficiently within a
single program.
THREADS
-
Multi-threaded applications
have multiple threads within
a single process
-
each thread have its own
program counter, stack and
set of registers,
-
All threads
share common
code, data, and certain
structures such as open
files.
THREADS
-
Threads are very useful in modern programming whenever a
process has multiple tasks to perform independently of the
others.
-
This is particularly true when one of the tasks may block, and
it is desired to allow the other tasks to proceed without
blocking.
-
For example in a word processor, a background thread may check
spelling and grammar while a foreground thread processes user
input ( keystrokes ), while yet a third thread loads images
from the hard drive, and a fourth does periodic automatic
backups of the file being edited.
THREADS
-
A multi-threaded application running on a single-core chip
would have to interleave the threads
-
A multi-threaded application running on a multi-core chip, the
threads could be spread across the available cores, allowing
true parallel processing
THREADS
-
The thread scheduler gives no guarantee about the order in
which threads are executed.
-
Each thread runs for a short amount of time, called a time
slice. Then the schedule activates another thread. However,
there will always be slight variations in running times. Thus,
you should expect that the order in which each thread gains
controls is somewhat random.
-
It is important to observe that the order and the timing of
operations performed by the threads are controlled by the
runtime system, and cannot be controlled by the programmer.
JAVA THREADS
-
The JVM executes each thread for a short amount of time and
then switches to another thread.
-
In a multithreaded environment, threads can be: created,
scheduled to run, paused, resumed, and terminated.
-
In Java, we can create threads within that process two
different ways
-
Create a new class of type Thread
-
-
java.lang.Thread
Create a new class that implements the Runnable interface
-
java.lang.Runnable
-
the Runnable interface has a single method called run().
JAVA THREADS
To create threads by creating a new class of type Thread
1.
Create a class that extends the Thread class.
2.
Override the run() method by placing the task code into
the run() method of your class.
3.
Create an object of the subclass
4.
Call the start method to start the thread
public class MyThread extends Thread {
@Override
public void run() {
// your code here!
}
public static void main( String[] args ){
MyThread thread = new MyThread();
thread.start();
}
}
main
-
thread
JAVA THREADS
To create threads by creating a new class that implements the
Runnable interface:
1.
Create a class that implements the Runnable interface.
2.
Place the task code into the run() method of your class.
3.
Create an object of the subclass
4.
Construct a thread object from the Runnable object.
5.
Call the start method to start the thread
public class MyRunnable implements Runnable {
public void run() {
// your code here!
}
public static void main( String[] args ){
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
}
main
-
thread
JAVA THREADS
-
Main Thread
public class MainThreadDemo {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println("Current thread: " + t);
t.setName("My Thread"); // set the thread name
System.out.println("After name change: " + t);
The sleep() method
try {
puts the current
for(int i = 5; i > 0; i--) {
thread to sleep for a
System.out.println(i);
given number of
Thread.sleep(500);
milliseconds
}
}
catch(InterruptedException e) {
}
Current thread: Thread[main,5,main]
After name change: Thread[My Thread,5,main]
}
5
}
4
3
2
1
Creating a thread by extending the Thread class
public class MyThreadDemo {
public static void main(String[] args) {
MyThread nt = new MyThread();
nt.start();
try {
for(int i = 5; i > 0; i--) {
System.out.printf("%-15s: %d\n", "Main Thread", i);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
}
System.out.println("Exiting Main Thread ...");
}
}
main
public class MyThread extends Thread{
public MyThread() {
super("Demo Thread");
System.out.println("Child Thread: " + this);
}
// This is the entry point for the second thread.
@Override
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.printf("%-15s: %d\n", "Child Thread", i);
Thread.sleep(500);
}
}
catch(InterruptedException e) {
}
System.out.println("Exiting Child Thread ...");
}
}
thread
Child Thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting Child Thread ...
Main Thread: 2
Main Thread: 1
Exiting Main Thread ...
Creating a thread by implementing the Runnable interface
// This is the entry point for the second thread.
@Override
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.printf("%-15s: %d\n", "Child Thread", i);
Thread.sleep(500);
}
}
catch(InterruptedException e) {
}
System.out.println("Exiting Child Thread ...");
}
}
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
try {
for(int i = 5; i > 0; i--) {
System.out.printf("%-15s: %d\n", "Main Thread", i);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
}
System.out.println("Exiting Main Thread ...");
}
}
main
public class MyRunnable implements Runnable{
thread
Main Thread
: 5
Child Thread
: 5
Child Thread
: 4
Main Thread
: 4
Child Thread
: 3
Child Thread
: 2
Main Thread
: 3
Child Thread
: 1
Exiting Child Thread ...
Main Thread
: 2
Main Thread
: 1
Exiting Main Thread ...
THREAD SYNCHRONIZATION
-
When threads share access to a common object, they can
conflict with each other. The shared access creates a problem.
This problem is often called a race condition.
-
To solve the problem use a lock mechanism. The lock mechanism
is used to control the threads that want to manipulate a
shared object.
THREAD SYNCHRONIZATION
-
To acquire the lock the code calls a synchronized method.
-
Methods that contain threed sensitive code are tagged with the
synchronized keyword.
-
When a thread calls a synchronized method on a shared object,
it owns that objects lock until it returns from the method
and thereby unlocks the object.
-
When an object is locked by one thread, no other thread can
enter a synchronized method for that object, the other thread
is automatically deactivated, and it needs to wait until the
first thread has unlocked the object.
THREAD SYNCHRONIZATION
-
When multiple threads need to update information stored in a
shared object, some ordering has to be enforced to avoid
unintended consequences.
-
Java provides a locking mechanism for this purpose!
-
When one thread wants to access the shared object, it has to
-
-
Lock the object
-
Complete its operations on the object
-
Unlock the object
This way, each thread will have exclusive access to the object
when the thread needs the object
Thread Synchronization - No Threads!
public class CallMe {
public void call(String message) {
System.out.print("[ ");
System.out.print(message);
System.out.print(" ]");
}
}
public class SyncDemo {
public static void main(String[] args) {
CallMe target = new CallMe();
target.call("No threads!");
}
}
[ No threads! ]
Thread Synchronization - No Synchronization
public class CallMe {
public void call(String message) {
System.out.print("[ ");
System.out.print(message);
System.out.print(" ]");
}
}
public class SyncDemo {
public static void main(String[] args) {
CallMe target = new CallMe();
Runnable callerA = new Caller(target, "Hello");
Runnable callerB = new Caller(target, "World");
Runnable callerC = new Caller(target, "Howdy Yall");
Thread threadA = new Thread(callerA);
Thread threadB = new Thread(callerB);
Thread threadC = new Thread(callerC);
threadA.start();
threadB.start();
threadC.start();
try {
threadA.join();
threadB.join();
threadC.join();
} catch (InterruptedException e) {
}
public class Caller implements Runnable {
String msg;
CallMe target;
public Caller(CallMe targ, String msg) {
this.target = target;
this.msg = msg;
}
@Override
public void run() {
target.call(msg);
}
}
The join() method
allows one thread to
wait until another
thread completes its
execution.
}
}
[ Hello[ Howdy Y'all ][ World ] ]
[ Hello ][ Howdy Y'all ][ World ]
[ Hello[ World ][ Howdy Y'all ] ]
Thread Synchronization - Method Synchronization
public class CallMe {
public synchronized void call(String message) {
System.out.print("[ ");
System.out.print(message);
System.out.print(" ]");
}
}
public class SyncDemo {
public static void main(String[] args) {
CallMe target = new CallMe();
Runnable callerA = new Caller(target, "Hello");
Runnable callerB = new Caller(target, "World");
Runnable callerC = new Caller(target, "Howdy Yall");
Thread threadA = new Thread(callerA);
Thread threadB = new Thread(callerB);
Thread threadC = new Thread(callerC);
threadA.start();
threadB.start();
threadC.start();
try {
threadA.join();
threadB.join();
threadC.join();
} catch (InterruptedException e) {
}
public class Caller implements Runnable {
String msg;
CallMe target;
public Caller(CallMe targ, String msg) {
this.target = target;
this.msg = msg;
}
@Override
public void run() {
target.call(msg);
}
}
}
}
[ Hello ][ Howdy Y'all ][ World ]
[ Hello ][ World ][ Howdy Y'all ]
Thread Synchronization - Block Synchronization
public class CallMe {
public void call(String message) {
System.out.print("[ ");
System.out.print(message);
System.out.print(" ]");
}
}
public class SyncDemo {
public static void main(String[] args) {
CallMe target = new CallMe();
Runnable callerA = new Caller(target, "Hello");
Runnable callerB = new Caller(target, "World");
Runnable callerC = new Caller(target, "Howdy Yall");
Thread threadA = new Thread(callerA);
Thread threadB = new Thread(callerB);
Thread threadC = new Thread(callerC);
threadA.start();
threadB.start();
threadC.start();
try {
threadA.join();
threadB.join();
threadC.join();
} catch (InterruptedException e) {
}
public class Caller implements Runnable {
String msg;
CallMe target;
public Caller(CallMe targ, String msg) {
this.target = target;
this.msg = msg;
}
@Override
public void run() {
synchronized(target){
target.call(msg);
}
}
}
}
}
[ Hello ][ Howdy Y'all ][ World ]
[ Hello ][ World ][ Howdy Y'all ]
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,215 @@
Application
Programming
Hend Alkittawi
Multi-threaded Apps
Building applications the utilize
threads
INTRODUCTION
-
Recall that a thread is a single sequence of execution, and
that code running within a single thread will execute one step
after another.
-
Every Android app starts life with a main thread. The main
thread,
however,
is not a pre-ordained list of steps.
Instead it sits in an infinite loop and waits for events
initiated by the user or the system. Then it excuse code and
response to those events as they occur.
-
So far, all of our Android apps has been executed on the main
thread.
INTRODUCTION
-
One of the key rules of Android development is to never perform
time-consuming operations on the main thread of an application.
-
The second rule is that the code within a separate thread must never, under
any circumstances, directly update any aspect of the user interface.
-
Any changes to the user interface must always be performed from within the
main thread.
-
The Android UI toolkit is not thread-safe. Attempts to work with
non-thread-safe code from within multiple threads will typically result in
intermittent problems and unpredictable application behavior!
-
If the code executing in a thread needs to interact with the user interface,
it must do so by synchronizing with the main UI thread. This is achieved by
creating a handler within the main thread, which, in turn, receives messages
from another thread and updates the user interface accordingly.
ANDROIDS MAIN THREAD
-
Regular threads vs the main thread
A Thread
Androids Main Thread
events
(from Android or User)
run some code
x
process an event
done
reproduced from book figure
ANDROIDS MAIN THREAD
-
The main thread in an Android application runs all the code
that updates the UI, including the code executed and response
to the different UI related events (activity startup,
button
presses, …).
-
because the events are all related to the UI and some way,
the main thread is sometimes called the UI thread.
-
The event loop keeps the UI code in sequence. It makes sure
that none of these operations step on each other while still
ensuring that the code is executed in a timely fashion.
BACKGROUND THREADS
-
Sometimes a task takes long time compared to
other tasks.
During that time, the UI will be
completely unresponsive,
which might result
in an Application Not Responding or ANR.
-
An ANR occurs when Androids watchdog
determines that the main thread has failed to
respond to an important event,
like pressing
the back button.
-
This is not the desired behavior for any
application.
WORD GENERATOR APP
-
Let us look at an app that
utilizes threads
public class WordGenerator {
public final int wordLength;
public WordGenerator(int wordLength){
this.wordLength = wordLength;
}
public String generateWord(){
String generatedWord = "";
Random rand = new Random();
for(int i = 0; i < wordLength; i++){
char randChar = (char) rand.nextInt(256);
generatedWord = generatedWord + randChar;
}
return generatedWord;
}
public class MainActivity extends AppCompatActivity {
private TextView generatorText;
private TextView counterText;
private Button generatorButton;
private Button counterButton;
private WordGenerator generator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generatorButton = findViewById(R.id.generator_button);
counterButton = findViewById(R.id.counter_button);
generatorText = findViewById(R.id.generator_text);
counterText = findViewById(R.id.counter_text);
generatorButton.setOnClickListener((view) -> startCounter());
}
counterButton.setOnClickListener((view) -> {
int count = Integer.parseInt(counterText.getText().toString());
counterText.setText(String.valueOf(count + 1));
});
runOnUiThread(runnable)runs the specified
action on the UI thread. If the current
thread is the UI thread, then the action
is executed immediately. If the current
thread is not the UI thread, the action
is posted to the event queue of the UI
thread.
}
}
public void startCounter() {
Thread thread = new Thread(() -> {
generator = new WordGenerator(5);
while (true) {
updateCounterText(generator.generateWord(), generatorText);
try {
Thread.sleep(500); // Update every half second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
}
public void updateCounterText(String text, TextView textView) {
runOnUiThread(() -> textView.setText(text));
}
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,406 @@
Application
Programming
Hend Alkittawi
Testing
Introduction to JUnit Framework for
Testing Java Code
INTRODUCTION
-
Testing in application programming/software development
Image Source: https://commons.wikimedia.org/wiki/File:SDLC_-_Software_Development_Life_Cycle.jpg
INTRODUCTION
-
Unit testing is a software testing method where individual
components of a software application, known as "units", are
tested in isolation from the rest of the application.
-
A unit is typically the smallest testable part of an
application, such as a function, method, or class.
-
Unit tests are designed to validate that each unit of the
software performs as expected. These tests are usually
automated and are written and run by software developers as
part of the development process.
UNIT TESTING
-
Unit testing is a systematic attempt to reveal errors
I DONT ALWAYS TEST
CODE
BUT WHEN I DO, I DO IT
IN PRODUCTION
<EFBFBD><EFBFBD>
UNIT TESTING
-
Importance of Unit Testing in Software Development
-
Early Detection of Issues
-
Improved Code Quality
-
Reduces Debugging Time
-
Promotes Confidence and Reliability
-
Cost Efficiency
-
Supports Continuous Integration and Continuous Deployment
-
Documentation
UNIT TESTING
-
For each method implemented, consider the following when
creating the test cases
-
Preconditions: Assumptions/requirements made on the parameters
or class variables to be used in the method.
-
Postconditions: Assumptions/requirements made on the returned
value (or updated class variables) at the end of the method.
JUNIT TESTING
-
JUnit is a widely used open-source testing framework for Java
programming language. It provides an easy-to-use framework for
writing and running repeatable tests.
-
JUnit has become the de facto standard for unit testing in
Java, integrated with various development environments and
build tools.
-
JUnit is linked as a JAR at compile-time
-
The framework resides under package org.junit
JUNIT TESTING
-
JUnit uses Java annotations to define test methods and manage
test life cycle events. Key annotations include:
-
@Test: Marks a method as a test method.
-
@Before: Runs before each test method to perform setup.
-
@After: Runs after each test method to perform cleanup.
-
@BeforeClass: Runs once before any of the test methods in the
class.
-
@AfterClass: Runs once after all the test methods in the
class.
-
@Ignore: Ignores the marked test method.
JUNIT ANNOTATIONS
JUNIT TESTING
-
JUnit provides a set of assertion methods to verify expected
outcomes, such as:
-
assertEquals(expected, actual)
-
assertNotEquals(unexpected, actual)
-
assertTrue(condition)
-
assertFalse(condition)
-
assertNull(object)
-
assertNotNull(object)
-
fail(message)
JUNIT IN ECLIPSE
-
JUnit integrates seamlessly with IDEs like Eclipse
-
To create a JUnit test in Eclipse
-
Create a new package, name it test, under your project (New >
Package)
-
Right-click on the test package > New JUnit Test Case
-
On the New JUnit Test Case wizard, select JUnit 4 and fill the
fields
-
Select which methods to be tested in the generated class
-
Add the JUnit library to the build path
-
Create the test methods and run the test
Create a new package under your project (New > Package)
Right-click on the test package > New JUnit Test Case
On the New JUnit Test Case wizard, select JUnit 4 and fill the highlighted
fields > Next
Select which methods are to be tested in the generated class > Finish
Add the JUnit library to the build path
Create the test methods and run the test
right-click in the text editor > Run As > JUint Test
package core;
package test;
public class StringUtils {
public class TestStringUtils {
public static String capitalize(String input) {
return input.toUpperCase();
}
@Ignore
public void testCapitalize() {
fail("Not yet implemented");
}
public static boolean isPalindrome(String str) {
if (str == null)
throw new IllegalArgumentException("Input string cannot be null");
@Test
public void testIsPalindromePalindromeString() {
boolean result = StringUtils.isPalindrome("racecar");
assertTrue(result);
}
str = str.toLowerCase();
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str.charAt(left++) != str.charAt(right--)) {
return false;
}
}
return true;
}
}
@Test
public void testIsPalindromeNonPalindromeString() {
boolean result = StringUtils.isPalindrome("hello");
assertFalse(result);
}
}
package core;
package test;
public class Calculator {
public class TestCalculator {
public int add(int a, int b) {
return a + b;
}
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
}
public int subtract(int a, int b) {
return a - b;
}
@Test
public void testAdd() {
assertEquals(5, calculator.add(2, 3));
assertEquals(-1, calculator.add(2, -3));
assertEquals(0, calculator.add(0, 0));
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) {
if (b == 0)
throw new IllegalArgumentException("Cannot divide by zero");
return a / b;
}
@Test
public void testSubtract() {
fail("Not yet implemented");
}
}
@Test
public void testDivide() {
assertEquals(2, calculator.divide(6, 3));
assertEquals(-2, calculator.divide(-6, 3));
assertEquals(0, calculator.divide(0, 5));
}
@Test(expected = IllegalArgumentException.class)
public void testDivisionByZero() {
calculator.divide(10, 0);
}
}
package core;
package test;
public class Car {
public class TestCar {
private String make;
private String model;
private int year;
private double fuelLevel;
@Test
public void testAddFuel() {
Car car = new Car("Toyota", "Camry", 2022);
car.addFuel(20.0);
assertEquals(20.0, car.getFuelLevel(), 0.0);
}
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
this.fuelLevel = 0.0;
}
@Test
public void testDriveWithEnoughFuel() {
Car car = new Car("Honda", "Accord", 2023);
car.addFuel(30.0);
car.drive(150.0); // Assuming 150 miles drive
assertEquals(15.0, car.getFuelLevel(), 0.0);
}
// getters, setters, and other methods
public void drive(double distance) {
if (fuelLevel > 0) {
fuelLevel -= distance / 10; // Assuming fuel consumption
// rate of 10 units per mile
}
}
@Test
public void testDriveWithInsufficientFuel() {
Car car = new Car("Ford", "Focus", 2021);
car.addFuel(10.0);
car.drive(150.0); // Assuming 150 miles drive
assertEquals(10.0, car.getFuelLevel(), 0.0);
}
}
}
CODE DEMO
-
Show how to create and
run JUnit tests in
Eclipse.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,146 @@
Application
Programming
Hend Alkittawi
Android Testing
Introduction to Testing Android Apps
ANDROID TESTING
-
There are two types of tests for unit testing in Android, both
of which use the JUnit testing framework
-
-
JVM tests for testing your Java code in the project.
-
Execute quickly (milliseconds) on your machines JVM
-
Located in the test source set (project > app > src > test)
Instrumented tests for testing code that uses the Android SDK
-
May take longer (seconds) on an emulator or Android device
directly
-
Located in the androidTest source set (project > app > src >
androidTest)
ANDROID TESTING
ANDROID TESTING
-
Shortcut to the “create a test” wizard: ctrl+shift+T (or
command+shift+T) when your cursor is inside of the class you
want to create a test for.
-
To run a test
-
Right click on the test class, choose “Run” OR Click ▶ next to
the test name to run
For instrumented tests, connect a device first (these tests
require a device - virtual or physical).
ANDROID TESTING
-
-
JVM Tests
-
Test the Java code in your project
-
Follow the same paradigms as the JUnit tests previously discussed
-
Naming conventions for classes and methods
-
Use of assert statements
Instrumented tests
-
Test code in your project which uses the Android SDK (e.g. Activity,
TextView, etc)
-
ActivityScenario provides APIs to start and drive an Activitys lifecycle
state for testing!
-
Espresso for Android UI testing
-
State expectations
-
Interactions
-
assertions
ACTIVITY LIFE CYCLE
-
As a user navigates through, out of, and back to your app, the
Activity instances in your app transition through different
states in their lifecycle.
-
The Activity class provides a number of callbacks that let the
activity know when a state changes or that the system is
creating, stopping, or resuming an activity or destroying the
process the activity resides in.
-
The activity lifecycle | Android Developers
ACTIVITY LIFE CYCLE
CODE DEMO
-
Show how to run
Android tests in
Android Studio.
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -0,0 +1,274 @@
Application
Programming
Hend Alkittawi
Final Exam Review
Youve Got This! ☺
IMPORTANT MIDTERM MATERIAL
Understand Java fundamentals
Classes and Objects
Variables and Methods [getters, setters, toString, equals,
object methods/variables, static methods/variables]
Class Relationships
Arrays, and ArrayLists
File I/O
UML diagrams
Code to diagram
Diagram to code
SOLID PRINCIPLES
Be familiar with the SOLID Principles
The Single Responsibility Principle (SRP)
The Open Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)
Understand why it is important to consider these principles
Rigidity
Immobility
Fragility
Viscosity
MVC
Be familiar with the “design architecture” concept
Understand what the MVC design architecture is
Be able to create an Android project that follows the MVC
design architecture
model
data storage,
integrity, consistency,
queries & mutations
controller
view
receive, interpret &
validate input, create &
update views, query and
modify models
presentation assets &
code
user
ANDROID BASICS
Be able to design a simple multi-screen, data-driven Android
application and provide the UML diagram for it.
Be able to create a layout XML file with basic views (Buttons,
TextViews, ImageViews, …)
Be able to create an Activity class as a controller class in
an Android app (listen to the user interactions, and manage
the flow of app data)
Understand how to utilize Java and Android APIs to perform I/O
operations (AssetsManager, InputStream, OutputStream, … )
EXCEPTIONS
Understand the difference between Java Exceptions and Java
Errors
Understand the difference between checked and unchecked
exceptions
Be familiar with Java exceptions (NullPointerException,
IOException, … )
Understand the difference between throwing an exception and
handling it
Understand what the call stack is
EXCEPTIONS
GENERICS AND COLLECTIONS
Understand the advantages of using generics in Java programs.
Be able to create classes and methods that utilize generic
types.
Understand the difference between the List, Map, and Set Java
collections.
Be able to use Java collections as part of a Java program.
Be able to utilize the following interfaces in a Java
application: Iterator, Iterable, Comparable, Comparator
LAMBDA EXPRESSIONS
Understand what a functional interface is
Understand what a lambda expression is
Be able to trace code that uses lambda expressions
Be able to write code that uses lambda expressions
Be able to use Javas functional interfaces in a Java
application
THREADS
Understand the difference between a process and a thread.
Be able to trace code that involves threads in Java.
Be able to create threads in Java by extending the Thread class.
Be able to create threads in Java by implementing the Runnable
interface.
Understand the importance of thread synchronization in Java
applications.
Understand the difference between the main thread (UI thread) and
other threads in an Android application.
Understand the importance of utilizing threads in an Android
application (preventing ANR).
UNIT TESTING
Be familiar with unit testing and the JUnit framework.
Be able to create basic test cases
VERSION CONTROL
Understand Git/Github terminology and workflow (local/remote
repo, stage, commit, push, pull)
DO YOU HAVE ANY
QUESTIONS?
THANK
YOU!
@
hend.alkittawi@utsa.edu
By Appointment
Online

View File

@ -25,26 +25,37 @@
| =CS3443= | =Online (zoom)= |
| =CS3424= | =Online (zoom)= |
* Courses :college:
* Courses :college:ARCHIVE:
** Applications Programming :cs3443:
- COURSE: =CS3443=
- LOCATION: =Online (zoom)=
*** TODO [#A] Applications Programming Mondays
SCHEDULED: <2024-06-24 Mon 10:00-12:00 ++1w>
SCHEDULED: <2024-08-05 Mon 10:00-12:00 ++1w>
:PROPERTIES:
:LAST_REPEAT: [2024-06-19 Wed 00:53]
:LAST_REPEAT: [2024-07-29 Mon 13:00]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-29 Mon 13:00]
- State "DONE" from "TODO" [2024-07-24 Wed 19:42]
- State "DONE" from "TODO" [2024-07-16 Tue 22:38]
- State "DONE" from "TODO" [2024-07-01 Mon 23:29]
- State "DONE" from "TODO" [2024-06-30 Sun 13:11]
- State "DONE" from "TODO" [2024-06-19 Wed 00:53]
:END:
*** TODO [#A] Applications Programming Wednesdays
SCHEDULED: <2024-06-26 Wed 10:00-12:00 ++1w>
SCHEDULED: <2024-08-07 Wed 10:00-12:00 ++1w>
:PROPERTIES:
:LAST_REPEAT: [2024-06-18 Tue 22:52]
:LAST_REPEAT: [2024-07-31 Wed 05:45]
:END:
:LOGBOOK:
- State "CANCELLED" from "TODO" [2024-07-31 Wed 05:45]
- State "DONE" from "TODO" [2024-07-24 Wed 19:41]
- State "DONE" from "TODO" [2024-07-19 Fri 01:28]
- State "DONE" from "TODO" [2024-07-16 Tue 22:38]
- State "DONE" from "TODO" [2024-07-03 Wed 23:29]
- State "DONE" from "TODO" [2024-06-30 Sun 13:11]
- State "CANCELLED" from "TODO" [2024-06-18 Tue 22:52]
- State "DONE" from "TODO" [2024-06-12 Wed 13:43]
:END:
@ -57,29 +68,43 @@ SCHEDULED: <2024-06-26 Wed 10:00-12:00 ++1w>
*** Systems Programming Lecture
**** TODO [#A] Systems Programming Lecture Mondays
SCHEDULED: <2024-06-24 Mon 16:00-18:00 ++1w>
SCHEDULED: <2024-07-29 Mon 16:00-18:00 ++1w>
:PROPERTIES:
:LAST_REPEAT: [2024-06-19 Wed 00:53]
:LAST_REPEAT: [2024-07-24 Wed 19:42]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-24 Wed 19:42]
- State "DONE" from "TODO" [2024-07-16 Tue 22:38]
- State "DONE" from "TODO" [2024-07-01 Mon 23:29]
- State "DONE" from "TODO" [2024-06-30 Sun 13:11]
- State "DONE" from "TODO" [2024-06-19 Wed 00:53]
:END:
**** TODO [#A] Systems Programming Lecture Wednesdays
SCHEDULED: <2024-06-26 Wed 16:00-18:00 ++1w>
SCHEDULED: <2024-07-31 Wed 16:00-18:00 ++1w>
:PROPERTIES:
:LAST_REPEAT: [2024-06-18 Tue 22:52]
:LAST_REPEAT: [2024-07-24 Wed 19:41]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-24 Wed 19:41]
- State "DONE" from "TODO" [2024-07-19 Fri 01:28]
- State "DONE" from "TODO" [2024-07-16 Tue 22:38]
- State "DONE" from "TODO" [2024-07-03 Wed 23:29]
- State "DONE" from "TODO" [2024-06-30 Sun 13:11]
- State "CANCELLED" from "TODO" [2024-06-18 Tue 22:52]
- State "DONE" from "TODO" [2024-06-13 Thu 09:34]
:END:
*** TODO [#A] Systems Programming Recitation
SCHEDULED: <2024-06-26 Wed 18:00-19:15 ++1w>
SCHEDULED: <2024-07-31 Wed 18:00-19:15 ++1w>
:PROPERTIES:
:LAST_REPEAT: [2024-06-18 Tue 22:52]
:LAST_REPEAT: [2024-07-24 Wed 19:41]
:END:
:LOGBOOK:
- State "DONE" from "TODO" [2024-07-24 Wed 19:41]
- State "DONE" from "TODO" [2024-07-19 Fri 01:28]
- State "DONE" from "TODO" [2024-07-16 Tue 22:38]
- State "DONE" from "TODO" [2024-07-03 Wed 23:29]
- State "DONE" from "TODO" [2024-06-30 Sun 13:11]
- State "CANCELLED" from "TODO" [2024-06-18 Tue 22:52]
- State "DONE" from "TODO" [2024-06-13 Thu 09:35]
:END: