CPSC 233 Notes
CPSC 233 Notes
Lecture 1 - 01/15
Object oriented programming involves breaking a program into specific entities. Encapsulation,
objects, and classes.
Classes are blueprints with functions/methods which objects are based off of.
Java can be used for standalone programs, as well as programs that run in a browser.
The only language a computer can actually understand is machine language. Everything else
must be translated from human languages to machine. For example, python or java are
translated to low level binary.
Python is an interpreted language. Every time a python project runs, it is translated from python
into machine code before it executes. Interpreted languages are slow, because they must be
translated every time it runs.
C/C++ is a compiled language. One time, before the program runs, the human language is
translated to machine language. This is true for most video games, as this is much faster.
Java is a 2 stage approach. A one time translation happens in the .java file to a lower level
language closer to machine language. This is very common and creates a .class file. In the
second step, the code is run as a bytecode file which is very close to machine language. THis
translation problem is quicker. Step 1 is compiling, step 2 is interpreting.
You need a different compiler for each operation system. An executable from a Mac computer
will not normally run on a Linux computer.
Java file → Java compiler → Java bytecode → Java interpreter → Java interpreter
Lecture 2 - 01/17
After installing Java you need to indicate to the operating system where the java compiler has
been installed.
Human languages are higher level, are interpretable by people and are similar to how we speak.
- Java, Python, C++
- Programming languages.
- English words are common.
- Even machine assembly is a higher level language.
Machine languages are low level, talk directly to the computer and are difficult for humans to
understand.
- Bytecode, binary.
Translation from high languages to low languages takes time. Interpreted languages take longer
than compiled ones.
A Jar file is a Java zip archive file. It is a compressed zip file of a Java program.
Java has much more rigid syntax than languages like Python. You have to write the public class
and public static void main chunks of code for classes and methods. This information is not
needed for Python.
Python methods return the address of values, not the actual value. Pass by reference vs pass
by value. In pass by value, you are directly copying the integer value to something else. Pass by
reference passes in the address of a value, not the direct value itself. For example, passing in
an entire list into a method, and then changing the list inside the method is pass by reference.
You don’t need to call the main method in java. This is syntactically enforced.
In Java variables must be declared before they can be used. This isn’t true for Python. Variable
declaration creates a variable in the memory. You must specify the name as well as the variable
type.
- Eg: int num = 0;
Variables can be initialized when they are declared which sets a starting value to them. If you
don’t do this, you could accidentally call a declared variable with no initialization and get an error
because there is no information attached.
Lecture 3 - 01/20
New terminology:
- Wrapper class: a class that is built around a primitive type. BigInteger, BigDecimal, ect
are wrapper classes. You can define behaviors around the data type that you want to
use. It is a clean implementation.
- Explicit typing: When you create a memory location, the type is explicitly declared. Eg.
int, float, string. You cannot mix and match variable types. In some programming
languages, like C, you can mix and max types. You can put an int value in a string for
example. This can result in crashes. This isn’t possible in Java. In Java, if this happens
you get a syntax/compiling error, not a runtime error. This makes it easier to fix.
Flexible and implicit type syntax Formal and explicit type syntax
Ability to quickly create very small programs Designed for any project. Explicit syntax
and applications. Scaling up can be difficult. makes scaling clever to manage. Small
programs can take time to create
Syntax is more sparse and clear. It is more Syntax is more computer type.
human readable.
Code is most often compiled to bytecode and Code is ALWAYS compiled to bytecode and
interpreted at the runtime. interpreted at runtime.
Java constants have ‘final’ before the type of the variable. They are variables that cannot be
changed. It is syntactically enforced.
Capitalizations help other programmers recognize constants. Constants must be in full caps.
Eg. E, PI, SIZE, ect. Multiple words are underscored.
In Java, the type of the quotient in division is determined by the type of the operands. If you are
dividing an int by a float, the result in a float.
Post and pre increment/decrementing. This means a variable is decreased by 1. It can either be
written as num-- (post decrement) or --num (pre decrement). The minus signs can also be + if
you are incrementing by 1. It usually doesn't matter if you are post or pre decrementing or
incrementing.
Casting is the ability to convert between data types (if it is sensible to do so). In Java the
conversion isn’t just limited to a limited number of functions. Python doesn’t truly have casting.
Lecture 4 - 01/22
Streams in programming: they are information coming from/going to the user. System.in and
System.out are examples of streams that go into and out of the program. You can redirect the
output of text programs. You can redirect the output to a specific file for example instead of
sending it to the console. E.g: ls > output.txt.
System is a class, out is an attribute (an instance of another class), println is a method. Many
things in Java are inbuilt classes, and work just like this. Out is an attribute of the type
printstream.
Error stream?
System.err.println(“error stream”);
Error streams are standard streams like print output streams. There is a difference between
error messages and error streams. An error stream is a stream that outputs error messages,
while an error message is the information displayed when a program encounters an error.
Text input is harder than Python. You can use the Scanner class to get text input from a user.
This isn’t inbuilt into Java, as you have to import java.util.Scanner to actually have access to the
class. You need to instantiate (create an instance of) the scanner class. The Scanner class has
methods that can get text input from the user.
When prompted for input the user types the information in and presses enter (end of line marker
EOL) to signal the end of the data to read. Only the nextLine() method can remove the end of
line from the input stream. This can cause problems when a non-string input is then followed by
the need to enter a string.
Primitive data types have a single memory location that can’t be decomposed.
Objects (arrays or lists, ect.) involve 2 memory locations: references to the object and the
object.
Branching
Brackets: boolean expressions in Java must be bracketed, which is not how it is in Python. ()
Braces: you must enclose branches, loops, and methods in braces. Nested constructs require a
pair of braces for each level of nested information. You should indent each nested construct.
This is just for visual ease. {}
Lecture 5 - 01/24
Switch cases must have a break to separate boolean expressions. The break transfers
execution out of the switch construct, otherwise cases will ‘fall-through.’ If you leave out the
break, it will continue through all switch cases until it hits a break. This doesn’t really make
sense with most instances where you are using switch cases.
Comparisons using the equality operator: the rule of thumb is to only this operator for primitive
data types. Don’t use it to compare objects. This only compares the address, not the actual
information.
Lecture 6 - 01/27
Variables have a specific scope within methods and classes, and cannot be accessed outside of
the scope they are defined within. For example, if you had a method called GetName in a
program and had a variable defined in the function called name, you could not access this
variable name outside of the function itself.
Java has looping constructs such as for and while. While loops begin with while(boolean
expression), followed by a body. The while can also be at the bottom of the loop, depending on
if you want the loop to check for another iteration at the beginning of the loop or the end.
In most languages, loops are usually used for counting. Iterating other sequences (such as lines
in a file) is generally not possible. In Java, the loop control update can be most any
mathematical expression, even something that is randomly assigned each time it iterates. In for
loops, you can have logical expressions within the control. You can have multiple expressions
as well to create very complex loop parameters. In Java, the stopping boundary of a loop is
explicit.
Pre-test loops test the boolean expression before executing the body of the loop. They execute
zero or more times. Post-test loops test the boolean expression after executing the body. They
execute either one or more times (cannot execute zero times as it checks for ending conditions
after the loop already runs once.)
Lecture 7 - 01/29
Iterating sequences: The regular for-loop in java can only be used if the sequence is numeric. It
is a counting loop. The for-each loop must be used to iterate over elements at a time. For-each
loops can be used for arrays, lists, and other data types in a similar vein.
For object oriented programming, you must declare an attribute and define a constructor for a
simple method.
Lecture 8 - 02/03
Memory can be accessed anywhere in your program, so long as the ‘public’ keyword is used
before static.
Final designated the memory location as unchangeable. THe initial value is the final value.
Static designates a memory location as associated with the class instead of associating the
memory location with each object created.
To define a method in Java, you need to have a return type, even if it is void to signify nothing
being returned.
Each class attribute and method has a modifier for access permissions:
- Public: attribute/method can be accessed anywhere in the program.
- Private: attribute/method can only be accessed in the class definition.
Lecture 9 - 02/05
Outside of a class definition, other classes can only access the private attributes through public
methods. Besides this, you cannot access private attributes outside of a class. Making attributes
private makes a program bigger, so why is it necessary?
Making attributes accessible only within a class and not outside of it is important because you
can divide up a program by different functionalities. If there are different people working on a
program, a class can return only the values needed, and other programers don’t need to be
aware of the internal workings of the class.
Public access for a class or method allows unlimited access anywhere in a program.
There are 2 mechanisms to pass data: pass by value, and pass by reference. Pass by value
directly passes in the information of a variable, which pass by reference only passes in the
address of data. Primitive types pass by value., not by reference.
Lecture 10 - 01/07
Structures
Composite structures are made of multiple parts. Some examples of these are lists/arrays, sets,
and dictionaries.
In Python, lists can be heterogeneous, where the element type can vary. Elements are
accessed via an index from 0 to the size -1. The size can be changed and updated. In Java.
These lists do not exist in the same way. They are called arrays, and must be homogeneous in
terms of element types. Elements are accessed via an index from 0 to the size -1, like Python
lists. The size is fixed and unchangeable.
Lecture 11 - 01/10
ArrayLists, HashSets, and HashMaps are closest to Python lists, sets, and dictionaries. These
are not used very often. In Java, you need to import these with java.util.ArrayLists because they
are not used very often. Regular Java lists are different from Python lists. ArrayList is a class
and includes many different methods. Instances can increase in size.
Implemented as containing but includes a consistent implementation for common operators are
class collections.
The type of each element would have to be homogeneous to iterate with a for-loop as a type for
a HashSet. HashMaps have many operations.
Version Control
GIT!
VCS/Version control systems allow changes in software to be stored in repositories. This allows
you to back up software by committing it to a repository by a push. Other programmers can get
changes to the software by pulling from a repository. The version control system keeps all
snapshots of the software over time so old commits can be accessed. Branches can occur
during development, so alternate versions can be stored as well.
You can make versions manually as well as using VCS software such as GIT. A repository
stores incremental changes, it doesn’t store the entire thing every time.
Checking out: a developer getting a local version of the software with the current version from
the repository.
Committing: a developer saving the local version of the software back into the repository.
Updating/pulling: a developer updating the local version of the software with the current version
in the repository.
Lecture 12 - 01/12
With version control, you commit changes almost like you are making a backup in the operating
system. Version control isn’t limited to just programming, you can use it for a lot of different
purposes.
Testing
Tests are important for finding bugs in programs. The first computer bug was an actual moth
that was in a machine. With large, complex systems, 50% of a system development budget
might be used for testing. Almost no software has no errors, so bug testing is very important.
Good programs have roughly 1 bug in every 100 lines.
Lecture 13 - 01/24
A class file can be used to query or examine a file which either refers to a physical file or a file
directory. Class file has many different methods.
Lecture 14 - 01/26
Exceptions
An exception is an event, which occurs during the execution of a program, that disrupts the
normal flow of the program's instructions. When an error occurs within a method, the method
creates an object and hands it off to the runtime system. An exception could happen in cases
where for example, the code is parsing an input int value but the input value is a string.
When writing to a file, there are primitives, strings, and objects that are inputs to the PrintWriter
which sends a char stream to a FileWriter, which then breaks it down to a byte stream which is
sent to the file. Reading files is the reverse process.
Input output is buffeted. Input does not directly pass from the input device to be processed by
the device. When a computer is busy, inputs can take a while to be processed (which is why a
mouse may lag when other things are consuming memory). Outputs are also buffered.
Commands that issue file writes are not instantly implemented.
A scanner will only read a file each time you make the request. This takes less memory stored
at one time. It is also slower because the I/O sends a request to the drive each loop, which is far
away from the CPU. A BufferedReader will pre-load a file into the active memory of a computer
and is faster.
Lecture 15 - 01/28
What to do when calling a method with exceptions? Method 1: include the call in try-construct
and include a corresponding catch-construct. Method 2: the calling method will also throw
exceptions.
Identity - how can you tell if two instances of an object are equal. What order should be put in?
You shouldn’t compare objects and arrays with the equality operator. You should use an equals
method to compare classes or compare a state.
To come up with classes for your program, break down the program into entities. This is a
classic approach. Utility classes are strictly designed to perform actions. They are not
instantiated but consist only of static methods. An example of this is the Math class. Actor
classes perform an action for individual instances, such as the Scanner class.