ITC 120 › Prelim › Stacks
Linear data structures · Lesson 3 of 4
Stacks
This lesson teaches:Data structureThe newest item leaves first, like the top plate on a pile.
By the end, you can:
- explain the last-in, first-out (LIFO) rule and name places where it fits;
- trace
push,pop, andpeekin a table, writing the stack from bottom to top and the value each call returns; - say what each
ArrayStackmethod changes indataandtop; - explain underflow and overflow, and how the code guards against them;
- trace a program that uses Java's own
Stack<Integer>, and explain what the<Integer>means.
You need: the Arrays and Linked lists lessons (for classes, objects, and nodes).
Part 1 · The big idea
A pile with one open end
After a handaan, the clean plates go on one pile. You put each washed plate on the top, and when someone needs a plate, they take the top one. The plate that went in last comes out first.
Stack
A stack is a linear data structure (its items form one line) where items are added and removed at one end only, called the top. It follows the LIFO rule: last in, first out. The item added most recently is the first one removed.
Here is the definition as a picture. Four items went in, one after another:
What makes something a stack is the rule "only touch the top," not what holds the items. The plates could sit on a table or a shelf; it is still a stack as long as you only add and take at the top. (In Part 4, a stack keeps its items in an array.) Describing something only by what you can do with it has a name, abstract data type; you will meet it in the Sets lesson.
Why follow such a strict rule? Many tasks only ever need the newest item (you will see some below). The rule keeps their order safe: nothing can be pulled from the middle and mix things up.
Here are the words that come with a stack:
| Word | Meaning | With the plates |
|---|---|---|
| top | the end where items enter and leave | the plate on top of the pile |
push(x) | add x on the top | put a clean plate on the pile |
pop() | remove the top item and return it | take the top plate |
peek() | return the top item, but keep it there | look at the top plate without taking it |
size() | how many items the stack holds | count the plates |
isEmpty() | true when there are no items | no plates left |
isFull() | true when a fixed-size stack has no room | the pile reaches the shelf above |
These names are conventions: ordinary method names that a programmer writes, not Java keywords. A different class could call them something else.
Underflow and overflow
Underflow: popping or peeking when the stack is empty (no plates left). Overflow: pushing onto a fixed-size stack that is already full (the shelf has no room).
Where you see LIFO
Here are three everyday places where the newest item comes out first:
Two more uses, which you will meet in later lessons:
| Use | How LIFO fits |
|---|---|
| Method calls in Java | Java keeps a stack of calls. A call is pushed when a method starts and popped when it finishes. You will see this in the Recursion lesson. |
| Depth-first search | A stack remembers the path back. You will use it in the DFS lesson. |
Undo and Back are illustrations of the rule, not a description of how any particular app is programmed.
Part 2 · Try it
Stack lab
Push three values, then pop them. In which order do they come out? Then try peek: what changes, and what does not?
Stack lab
Type a value, then push, pop, or peek. Every action is written in the log, like a trace table. Try popping an empty stack, or pushing a sixth value.
Stack (LIFO · capacity 5)
| Operation | Stack (bottom → top) | Returned |
|---|
Part 3 · Tracing
Tracing a stack in a table
A trace table shows the stack after every call. This is also the format for exams and coding exercises: one row per call, the stack written bottom → top with commas, and the value the call returns (— if it returns nothing). The stack starts empty, and each row acts on the result of the row before it:
| Call | Stack after (bottom → top) | Returned | size | What happens |
|---|---|---|---|---|
push(10) | 10 | — | 1 | 10 goes on; it is the top. |
push(20) | 10, 20 | — | 2 | 20 goes above 10; 20 is the top. |
peek() | 10, 20 | 20 | 2 | Reads the top. Nothing changes. |
push(30) | 10, 20, 30 | — | 3 | 30 is the new top. |
pop() | 10, 20 | 30 | 2 | Removes 30; 20 is the top again. |
pop() | 10 | 20 | 1 | Removes 20; only 10 is left. |
Exam traps
- Write the stack bottom → top. The newest item is written last (on the right), not first. So "10, 20, 30" means 30 is on top, like D in the A, B, C, D picture .
- A call removes even when nothing prints it. A line like
s.pop();still removes the top item. Its value is returned and simply not used, so write it in the Returned column anyway. peek()changes nothing. Copy the stack from the row above, and write the top value as Returned.
Part 4 · Java
A stack in Java, using an array
Array and index (from the Arrays lesson)
An array is a fixed number of cells side by side, all holding the same type. Each cell has an index, its position number, starting at 0. An array's length never changes, so the last index is length - 1.
Class and object (from the Linked lists lesson)
A class is a blueprint; an object is one real thing made from it with new (see the picture ). A Node object only held data. An ArrayStack object holds data in its fields (data and top) and has methods (push, pop, …) that work on that data.
Java has no class called ArrayStack. It is our own class, written in this lesson; the name just means "a stack that keeps its items in an array." Inside, it is an ordinary array plus one number, top, and the stack rule:
ArrayStack, drawn as a column. 4, 9, 2 are the stack, and top is 2, the index of the top item. The next push goes into cell 3. Cells 0 and 1 are still there, but the stack's methods only ever use the top.This also makes a stack fast. Adding or removing at the top never shifts other items (as inserting into the middle of an array does), so push and pop take the same few steps however big the stack gets.
The class ArrayStack keeps its items in an array called data. The field top is the index of the top item. A new stack has top = -1, meaning "no top item yet." The -1 is only an index; it is never returned as data. Why not start at 0? top = 0 would mean "the top item is in cell 0," so the stack would already hold one item.
1class ArrayStack {
2 int[] data; // cells that hold the stack items
3 int top; // index of the top item; -1 means empty
4
5 ArrayStack(int capacity) {
6 data = new int[capacity];
7 top = -1;
8 }
9 boolean isEmpty() {
10 return top == -1;
11 }
12 boolean isFull() {
13 return top == data.length - 1;
14 }
15 int size() {
16 return top + 1;
17 }
18 // ... push, pop, and peek below
19} Boolean method
A boolean method returns true or false. return top == -1; returns true exactly when top equals -1.
The three checks all come from the meaning of top:
| Method | Returns | Why |
|---|---|---|
isEmpty() | top == -1 | no top item yet |
isFull() | top == data.length - 1 | the top item is in the last cell |
size() | top + 1 | indexes start at 0, so top 1 means 2 items |
Exception and throw
An exception is an error Java reports while the program is running; if nothing handles it, the program stops. A method can report one itself when it cannot do its job: the throw statement stops the method at once with an exception object. IllegalStateException is Java's standard exception for "you asked at the wrong time," such as popping an empty stack. When the program stops, Java prints the exception's name and message.
To use a stack, a program makes one object with new, then calls its methods with a dot:
s has its own fields and its own methods. s.push(4) runs the push method of this stack, so only s changes.Read s.push(4); aloud as "stack s, push 4." If a program made two stacks, s and t, then t.push(4) would change only t: each object has its own data and top.
Now push, pop, and peek. Each one first checks for overflow or underflow, then does its job. Follow them on a new stack made with new ArrayStack(3). The array is drawn as a column, with index 0 at the bottom, so the top is really on top:
Walkthrough: push(4), push(9), pop(), peek(), then overflow
Use Next to go step by step, or tap a line to jump to it.
value = 4top = -1
The stack was just made with new ArrayStack(3), so top is -1: empty. The three cells hold Java's default 0, but they are all above top (dashed), so none of them is part of the stack. Now s.push(4) runs.
1void push(int value) { 2 if (isFull()) { 3 throw new IllegalStateException("Stack overflow: full."); 4 } 5 top++; // 1. move top up one cell 6 data[top] = value; // 2. store the value there 7} 8 9int pop() {10 if (isEmpty()) {11 throw new IllegalStateException("Stack underflow: empty.");12 }13 int value = data[top]; // 1. save the top value14 top--; // 2. move top down one cell15 return value;16}1718int peek() {19 if (isEmpty()) {20 throw new IllegalStateException("Stack underflow: empty.");21 }22 return data[top]; // look only; top does not change23} What each method changes
push moves top up one cell, then stores the value there. pop saves the value at top, moves top down, and returns the saved value. peek changes nothing: it returns data[top] and leaves top alone.
Why not return -1 when the stack is empty?
-1 could be real data: a stack of temperatures might hold -1. Throwing an exception makes the mistake impossible to miss. The rule: check isEmpty() before popping or peeking, and isFull() before pushing onto a fixed-size array.
The whole program
Here is everything in one runnable file. main does the same calls as the walkthrough, except the last push(8). To see the overflow exception, add s.push(8); at the end of main.
1public class Main {
2 public static void main(String[] args) {
3 ArrayStack s = new ArrayStack(3);
4 s.push(4);
5 s.push(9);
6 System.out.println(s.pop()); // 9
7 System.out.println(s.peek()); // 4
8 s.push(2);
9 s.push(7);
10 System.out.println(s.size()); // 3
11 System.out.println(s.isFull()); // true
12 }
13}
14
15class ArrayStack {
16 int[] data; // cells that hold the stack items
17 int top; // index of the top item; -1 means empty
18
19 ArrayStack(int capacity) {
20 data = new int[capacity];
21 top = -1;
22 }
23 boolean isEmpty() {
24 return top == -1;
25 }
26 boolean isFull() {
27 return top == data.length - 1;
28 }
29 int size() {
30 return top + 1;
31 }
32 void push(int value) {
33 if (isFull()) {
34 throw new IllegalStateException("Stack overflow: full.");
35 }
36 top++;
37 data[top] = value;
38 }
39 int pop() {
40 if (isEmpty()) {
41 throw new IllegalStateException("Stack underflow: empty.");
42 }
43 int value = data[top];
44 top--;
45 return value;
46 }
47 int peek() {
48 if (isEmpty()) {
49 throw new IllegalStateException("Stack underflow: empty.");
50 }
51 return data[top];
52 }
53} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Java's own stack: Stack<Integer>
Java has no ArrayStack, but it does come with ready-made stack classes, so real programs seldom write their own. The oldest is java.util.Stack, and exams often ask you to trace it. It has the same five methods as our ArrayStack: push, pop, peek, isEmpty, and size. Here is a short program that uses it:
1import java.util.Stack;
2
3public class Main {
4 public static void main(String[] args) {
5 Stack<Integer> stack = new Stack<>();
6 stack.push(10);
7 stack.push(20);
8 stack.push(30);
9 System.out.println(stack.peek());
10 System.out.println(stack.pop());
11 System.out.println(stack.size());
12 System.out.println(stack);
13 stack.pop();
14 System.out.println(stack.isEmpty());
15 System.out.println(stack.pop());
16 System.out.println(stack.isEmpty());
17 }
18} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Two lines are new. This table shows how to read them aloud:
| Code | Read it as | What it means |
|---|---|---|
import java.util.Stack; | "use the Stack class from java.util" | java.util is Java's toolbox of ready-made data structures. Without this line, Java does not know the name Stack. |
Stack<Integer> stack | "stack is a Stack of Integers" | The type inside < > says what kind of items the stack holds. |
= new Stack<>() | "make a new, empty Stack" | The empty <> copies the type from the left side. There is no capacity: a Stack grows by itself, so it never overflows. |
System.out.println(stack) | "print the whole stack" | Prints every item in square brackets, bottom → top, like [10, 20]. That is the same order as our trace tables. |
Generics: the type in < >
A class like Stack can hold any type of item. You choose the type in angle brackets when you make one: Stack<Integer> holds whole numbers, and Stack<String> holds strings. This feature is called generics. Java then checks every call for you: stack.push("hi") on a Stack<Integer> is a compile error.
Why Integer, not int?
The type inside < > must be a class, and int is not a class (it is a primitive type). Integer is the class version of int. Java converts between the two for you, so stack.push(10) and int x = stack.pop(); just work. Stack<int> is a compile error. You will see the same <Integer> again in Queues, Graphs, BFS, and Maps.
Now trace the program in a table, the same way as Part 3. Try it on paper first, then check:
Show the trace and the output
One row per line that calls the stack. "Printed" is what println shows; a call can return a value that nothing prints.
| Line | Call | Stack after (bottom → top) | Returned | Printed |
|---|---|---|---|---|
| 6 | push(10) | 10 | — | |
| 7 | push(20) | 10, 20 | — | |
| 8 | push(30) | 10, 20, 30 | — | |
| 9 | peek() | 10, 20, 30 | 30 | 30 |
| 10 | pop() | 10, 20 | 30 | 30 |
| 11 | size() | 10, 20 | 2 | 2 |
| 12 | print the stack | 10, 20 | — | [10, 20] |
| 13 | pop() | 10 | 20 | (not printed) |
| 14 | isEmpty() | 10 | false | false |
| 15 | pop() | (empty) | 10 | 10 |
| 16 | isEmpty() | (empty) | true | true |
Output (checked in Java):
30
30
2
[10, 20]
false
10
true The newer choice: ArrayDeque
Stack dates from the first version of Java, and it has extra methods that break the stack rule (for example, get(0) reads the bottom item). Java's documentation says to use a deque ("deck," a double-ended queue) instead, such as ArrayDeque, which is also usually faster. It has the same push, pop, and peek:
1import java.util.ArrayDeque;
2
3public class Main {
4 public static void main(String[] args) {
5 ArrayDeque<Integer> stack = new ArrayDeque<>();
6 stack.push(10);
7 stack.push(20);
8 stack.push(30);
9 System.out.println(stack.pop()); // 30
10 System.out.println(stack.peek()); // 20
11 System.out.println(stack); // [20, 10] top first!
12 }
13} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Exam trap: printing an ArrayDeque
println shows an ArrayDeque top first: [20, 10]. A Stack with the same items prints [10, 20]. The stack is the same (20 is on top); only the printing order differs. In a trace table, still write the stack bottom → top.
The three stacks side by side:
Our ArrayStack | Java's Stack | Java's ArrayDeque | |
|---|---|---|---|
| Items kept in | a fixed-size array | an array that grows | an array that grows |
| Can it get full? | yes (overflow) | no | no |
pop() when empty | IllegalStateException | EmptyStackException | NoSuchElementException |
peek() when empty | IllegalStateException | EmptyStackException | returns null (no exception) |
println order | (we did not write one) | bottom → top | top → bottom |
| Use it for | learning what happens inside | exams and older code | new programs |
All three are the same stack ADT: the same LIFO rule and the same methods, kept in different ways. In this course you still write your own, so you can see what happens inside.
Good to know: StackOverflowError
You may also meet StackOverflowError. That is overflow on Java's own stack of method calls, usually from a recursive method that never stops. You will see it in the Recursion lesson.
A stack built from a linked list
A stack can also use a linked list, with the first node as the top. Then push is "insert at the beginning" and pop is "delete the first node," the same two operations from the Linked lists lesson. It never gets full, so it has no isFull().
1class LinkedStack {
2 Node top; // the first node is the top; null means empty
3
4 void push(int value) {
5 Node newNode = new Node(value);
6 newNode.next = top; // step 1: the new node points to the old top
7 top = newNode; // step 2: top moves to the new node
8 }
9 int pop() {
10 if (top == null) {
11 throw new IllegalStateException("Stack underflow: empty.");
12 }
13 int value = top.data;
14 top = top.next; // delete the first node
15 return value;
16 }
17} It uses the same Node class as the Linked lists lesson. LIFO is the rule; an array or a linked list is just where the items are kept.
Part 5 · Watch out
Common mistakes
Mistake 1: storing before moving top
Situation: a student swaps the two lines of push:
data[top] = value; // stores first...
top++; // ...then moves What goes wrong: top is the index of the current top item. On an empty stack, data[-1] = value; crashes with an ArrayIndexOutOfBoundsException. On a stack holding 4, 9, the new value writes over the 9.
Fix: move first (top++;), then store (data[top] = value;).
Mistake 2: thinking pop erases the cell
Situation: after pop() on 4, 9, a student writes that data[1] is now 0.
What goes wrong: pop only moves top down. The 9 is still in cell 1 (see step 9 of the walkthrough). It is not part of the stack because it is above top, and the next push writes over it.
✗ After pop()data = [4, 0, 0]
✓ After pop()data = [4, 9, 0], top = 0
Mistake 3: using peek to remove
Situation: a program calls peek() in a loop, hoping to empty the stack.
What goes wrong: peek() never moves top, so it returns the same top item every time and the stack never shrinks.
Fix: use pop() to remove; use peek() only to look.
Part 6 · Your turn
Practice
Set A is the Section 5 self-check from your module, in case you want to redo it. Set B is new. The coding task at the end runs in Java.
Set A: from the module
- Write exactly what this prints.
ArrayStack s = new ArrayStack(3); s.push(4); s.push(9); System.out.println(s.pop()); s.push(2); System.out.println(s.peek()); System.out.println(s.size()); System.out.println(s.isFull()); - In your own words, what is the difference between
pop()andpeek()? Which line of code shows it?
Show the answers
9,2,2,false(one per line).pop()removes 9. Afterpush(2)the stack is 4, 2, sopeek()shows 2 andsize()is 2. With capacity 3, it is not full.pop()removes the top item and returns it;peek()returns it and leaves the stack unchanged. The linetop--;inpop()is the difference.
Set B: new problems
- The statements run in order, starting with an empty stack. Copy the table and fill it in. The first row is done for you.
ArrayStack s = new ArrayStack(4); s.push(5); s.push(8); s.pop(); s.push(3); s.push(6); s.peek(); s.pop(); s.pop();Statement Stack after (bottom → top) Value returned s.push(5);5 — s.push(8);s.pop();s.push(3);s.push(6);s.peek();s.pop();s.pop(); - Inside the array. After this code, (a) what is
top? (b) What is indata[1]anddata[2]? (c) Is 33 part of the stack? Why?ArrayStack s = new ArrayStack(3); s.push(11); s.push(22); s.push(33); s.pop(); s.pop(); s.push(44); - Push the characters of
IT2Cone at a time (I first), then pop until the stack is empty. Write the characters in the order they come out. - What does this print? What happens on the last line?
ArrayStack s = new ArrayStack(2); s.push(1); System.out.println(s.pop()); System.out.println(s.pop());
Show the answers
For self-study, not for grading. All answers were checked by running the code in Java.
-
Statement Stack after (bottom → top) Value returned s.push(5);5 — s.push(8);5, 8 — s.pop();5 8 s.push(3);5, 3 — s.push(6);5, 3, 6 — s.peek();5, 3, 6 6 s.pop();5, 3 6 s.pop();5 3 - (a)
topis 1. After the two pops it was 0;push(44)moved it to 1. (b)data[1]is 44 (it wrote over 22), anddata[2]is still 33. (c) No. 33 is abovetop, so it is not part of the stack. The stack is 11, 44. C,2,T,I. C was pushed last, so it comes out first: the word comes out reversed, C2TI.- It prints
1. The secondpop()finds the stack empty, so it throws anIllegalStateExceptionwith the message "Stack underflow: empty." and the program stops (underflow).
Your coding task: decimal to binary
To write a number in binary, divide it by 2 again and again, and keep each remainder. The catch: the remainders come out in the wrong order. The last remainder is the first binary digit. A stack fixes that for free: push each remainder, then pop them all. Here is 6, step by step:
n | n % 2 (push it) | n / 2 (the new n) |
|---|---|---|
| 6 | 0 | 3 |
| 3 | 1 | 1 |
| 1 | 1 | 0, so stop |
The stack now holds 0, 1, 1 (bottom → top). Popping gives 1, 1, 0, so 6 is 110 in binary.
Finish toBinary in about 6 lines where it says YOUR CODE. ArrayStack is the class from Part 4, with only the methods this task needs. Run it: each printed line must match its comment.
1public class Main {
2 // Returns n written in binary, for example toBinary(6) gives "110".
3 static String toBinary(int n) {
4 if (n == 0) {
5 return "0";
6 }
7 ArrayStack s = new ArrayStack(32);
8 String result = "";
9 // YOUR CODE:
10 // 1. While n > 0: push the remainder n % 2,
11 // then divide: n = n / 2.
12 // 2. While the stack is not empty: pop a digit
13 // and add it to the end of result.
14
15 return result;
16 }
17
18 public static void main(String[] args) {
19 System.out.println(toBinary(6)); // expected: 110
20 System.out.println(toBinary(13)); // expected: 1101
21 System.out.println(toBinary(20)); // expected: 10100
22 System.out.println(toBinary(1)); // expected: 1
23 System.out.println(toBinary(0)); // expected: 0
24 }
25}
26
27class ArrayStack {
28 int[] data;
29 int top;
30
31 ArrayStack(int capacity) {
32 data = new int[capacity];
33 top = -1;
34 }
35 boolean isEmpty() {
36 return top == -1;
37 }
38 boolean isFull() {
39 return top == data.length - 1;
40 }
41 void push(int value) {
42 if (isFull()) {
43 throw new IllegalStateException("Stack overflow: full.");
44 }
45 top++;
46 data[top] = value;
47 }
48 int pop() {
49 if (isEmpty()) {
50 throw new IllegalStateException("Stack underflow: empty.");
51 }
52 int value = data[top];
53 top--;
54 return value;
55 }
56} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Show one possible answer
1static String toBinary(int n) {
2 if (n == 0) {
3 return "0";
4 }
5 ArrayStack s = new ArrayStack(32);
6 String result = "";
7 while (n > 0) {
8 s.push(n % 2);
9 n = n / 2;
10 }
11 while (!s.isEmpty()) {
12 result = result + s.pop();
13 }
14 return result;
15} Output, one per line: 110, 1101, 10100, 1, 0.
n / 2 divides two ints, so the decimal part is dropped: 13 / 2 is 6. The part that was dropped is exactly n % 2, the remainder we push. The first loop stops when n reaches 0.
The second loop is the stack doing its job. The remainders went in last-digit-first, and LIFO brings them out first-digit-first, just as IT2C came out as C2TI in Set B. result + s.pop() joins text and a number, so "" + 1 gives "1", then "1" + 1 gives "11", and so on.
Why the if (n == 0) at the start? With 0, the first loop never runs, nothing is pushed, and result stays empty. But 0 in binary is 0, not an empty line.
Part 7 · Check yourself
Self-check
Not graded. Tap an answer to see if you got it, and read why.
-
A stack follows which rule?
A stack is LIFO: the item added most recently is removed first, like the top plate of a pile.
-
Push 1, push 2, push 3, then pop. What is returned?
3 was pushed last, so it is on top.
pop()removes and returns 3. -
What is the difference between
pop()andpeek()?Both return the top item, but only
pop()movestopdown (top--;).peek()leaves the stack unchanged. -
In
ArrayStack, a new stack hastop = -1. What doessize()return?size()returnstop + 1, which is 0. The -1 is only an index meaning "no top item yet." -
An
ArrayStackholds 4, 9 (sotopis 1). Afterpop(), what is indata[1]?pop()only movestopdown to 0. The 9 stays in cell 1, but it is abovetop, so it is not part of the stack. The nextpushwrites over it. -
A program runs
s.pop();on its own line, without printing it. What happens?pop()always removes the top item. Printing or storing the returned value is up to the program. -
Why does
pushruntop++;beforedata[top] = value;?topis the index of the current top item. Storing first would write over that item (or use index -1 on an empty stack). Moving up first gives the new value its own cell. -
After
Stack<Integer> s = new Stack<>(); s.push(5); s.push(6); s.push(7); s.pop();what doesSystem.out.println(s);print?pop()removed 7, the top. AStackprints bottom → top, so [5, 6]. (AnArrayDequewould print [6, 5], top first.) -
Why does
Stack<int>not compile?Generics need a class type. Use
Integer, the class version ofint; Java converts between them for you.
Score: 0 / 9
Key takeaways
- Stack: last in, first out.
push,pop, andpeekall happen at the top. popremoves and returns the top item;peekonly looks.- In
ArrayStack,topis the index of the top item: -1 means empty, and the size istop + 1. pushmovestopup, then stores.popleaves the old value in its cell, abovetop.- Guard against underflow (empty) and overflow (full) before acting.
Next lesson: Queues, where the oldest item leaves first.
References
- R. Sedgewick and K. Wayne, Algorithms, 4th ed. Addison-Wesley, 2011, Section 1.3 (Bags, Queues, and Stacks). algs4.cs.princeton.edu
- P. Morin, "ArrayStack: Fast Stack Operations Using an Array," Section 2.1 in Open Data Structures. opendatastructures.org
- Oracle, "Class IllegalStateException," Java SE 21 API. docs.oracle.com
- Oracle, "How to Throw Exceptions," The Java Tutorials. docs.oracle.com
- ITC 120 Data Structures and Algorithms Syllabus, Faculty of Computing, Engineering, and Technology, Davao Oriental State University.