Software Development
Languages
I consider myself proficient in the following languages:
- Python
- Java
- R
I have worked briefly with the following languages and would be able to learn them quickly:
- Javascript (including Node.js)
- C
- HTML/CSS
Dev Skills
- Object-Oriented Programming
- Git and GitHub/Lab
- Unix-based CLI (Bash)
- Scrum, Kanban, Scrumban
- Data Analysis
Code Samples
Java
Implement a Binary Search Tree: CS-242 Data Structures
I was tasked with writing certain methods for the Binary Search Tree:
size(), height(), contains(), find(), add(), and remove().
/**
Compute the number of nodes in a binary tree
@param aNode the reference to the root of a binary tree
(which may be an empty tree with a null root)
@return the number of elements in the tree with the given root
*/
public int size() {
return size (root);
}
private int size(Node aNode) {
int count = 0;
if (aNode == null) return 0;
if (aNode.left != null) {
count = count + size(aNode.left);
}
count++;
if (aNode.right != null) {
count = count + size(aNode.right);
}
return count;
}
/**
Compute the height of a binary tree
@param aNode the reference to the root of a binary tree
(which may be an empty tree with a null root)
@return the height of the tree with the given root. If the
tree is null, -1 is returned.
*/
public int height() {
if (root == null) return -1;
return height(root); // REMOVE THIS LINE WHEN YOU ARE DONE
// TO BE COMPLETED BY THE STUDENT
}
private int height (Node aNode) {
int maxHeight = 0;
if (aNode.left == null && aNode.right == null) {
maxHeight = 0;
return maxHeight;
}
else{
int heightLeft = 0;
int heightRight = 0;
if (aNode.left != null)
heightLeft = 1 + height (aNode.left);
if (aNode.right != null)
heightRight = 1 + height (aNode.right);
if(heightLeft >= heightRight) return maxHeight + heightLeft;
else return maxHeight + heightRight;
}
}
/**
Searches for a given element in the binary search tree
@param someElement element to be searched
@return true - if someElement is found in the tree;
false otherwise
Complexity: O(h) - where h is the height of the tree.
In the worst case it could be O(n). But on aveage
we can expect a complexity of O(log n)
*/
public boolean contains( E someElement) {
Node aNode = root;
if (root == null) return false;
if (aNode.data.compareTo(someElement) == 0) return true;
else {
while (aNode.data.compareTo(someElement) != 0) {
if(aNode.data.compareTo(someElement) < 0) {
if (aNode.right == null) return false;
else aNode = aNode.right;
}
else {
if (aNode.left == null) return false;
else aNode = aNode.left;
}
}
return true;
}
}
/**
Searches for a given element in the binary search tree
@param someElement element to be searched
@param count keeps track of the number of comparisons
for this search
@return E - if someElement is found in the tree; null
otherwise
// Complexity: O(h) - where h is the height of the tree.
// In the worst case it could be O(n). But on aveage
// we can expect a complexity of O(log n)
*/
public E find (E someElement, IntObject count) {
if(root == null) return null;
Node aNode = root;
count.setData(count.getData() + 1);
while (aNode.data.compareTo(someElement) != 0) {
if(aNode.data.compareTo(someElement) > 0) {
if (aNode.left == null) return null;
else aNode = aNode.left;
}
else {
if(aNode.right == null) return null;
else aNode = aNode.right;
}
count.setData(count.getData() + 1);
}
return aNode.data;
}
/**
inserts an element into a BST
@param someElement element that needs to be inserted
@param count keeps track of the number of comparisons
done for this insert
@return true if the insertion is successful, false otherwise
Complexity: O(h) - where h is the height of the tree.
In the worst case it could be O(n). But on aveage
we can expect a complexity of O(log n)
*/
public boolean add(E someElement) {
if (root == null) {
root = new Node (someElement);
return true;
}
else {
Node aNode = root;
if (aNode.data.compareTo(someElement) == 0) return false;
while (aNode.data.compareTo(someElement) != 0) {
if (aNode.data.compareTo(someElement) < 0) {
if (aNode.right == null) {
Node addedNode = new Node (someElement);
aNode.right = addedNode;
return true;
}
else aNode = aNode.right;
}
else {
if(aNode.left == null) {
Node addedNode = new Node (someElement);
aNode.left = addedNode;
return true;
}
else aNode = aNode.left;
}
}
return false;
}
}
/**
removes an element from a BST
@param someElement element that needs to be deleted
@return returns true if someElement is found in the tree and is
successfully deleted; returns false if someElement is
not found in the tree.
Complexity: O(h) - where h is the height of the tree.
In the worst case it could be O(n). But on aveage
we can expect a complexity of O(log n)
*/
public boolean remove(E someElement) {
if (root == null) return false; //empty tree
Node aNode = root;
Node parent = null;
while (aNode.data.compareTo(someElement) != 0) { // The node has a different value than the one we're searching for
if(aNode.data.compareTo(someElement) > 0) {
if (aNode.left == null) return false; // element not in tree and cannot be removed
else { // move to the left subtree
parent = aNode;
aNode = aNode.left;
}
}
if(aNode.data.compareTo(someElement) < 0) {
if (aNode.right == null) return false; // element not in tree and cannot be removed
else { //move the the right subtree
parent = aNode;
aNode = aNode.right;
}
}
}
//Found the node
//case 1: the node is a leaf
if (aNode.left == null && aNode.right == null) { // leaf
if (aNode.data.equals(root.data)) {//leaf is the root
root = null;
}
else {// leaf is not the root
if (parent.right != null && parent.right.equals(aNode)) {// node is right-child of parent
parent.right = null;
}
else if (parent.left != null && parent.left.equals(aNode)) { // node is left-child
parent.left = null;
}
aNode = null;
}
return true;
}
else if (aNode.left == null && aNode.right != null) {//aNode has only a right child
if(aNode.data.equals(root.data)) {// aNode is the root
root = aNode.right;
}
else {//aNode is not the root
if(parent.right != null && parent.right.equals(aNode)) {// node is the right-child of its parent
parent.right = aNode.right;
aNode = null;
}
else if (parent.left != null && parent.left.equals(aNode)) {// node is the left-child of its parent
parent.left = aNode.right;
aNode = null;
}
}
return true;
}
else if (aNode.left != null && aNode.right == null) { // node has only a left child
if(aNode.data.equals(root.data)) {//node is the root
root = aNode.left;
}
else {
if(parent.right != null && parent.right.equals(aNode)) {//node is the right-child of its parent
parent.right = aNode.left;
aNode = null;
}
else if (parent.left != null && parent.left.equals(aNode)) {
parent.left = aNode.left;
aNode = null;
}
}
return true;
}
else if (aNode.left != null && aNode.right != null) {
Node temp = aNode.right;
if(parent == null) {//aNode is the root
aNode.data = delete(temp.getLeftMostData());
return true;
}
else if(parent.right != null && parent.right.equals(aNode)) {
aNode.data = delete(temp.getLeftMostData());
return true;
}
else if(parent.left != null && parent.left.equals(aNode)) {
aNode.data = delete(temp.getLeftMostData());
return true;
}
else return false;
}
else return false;
}
Project Details
- Recursion
- Binary Search Trees
- Conditionals, iteration
Implement a Dequeue: CS-242 Data Structures
I was provided an abstraction of a student object and was tasked to implement a dequeue
using a circular array. I was provided a JUnit test suite.
import java.util.Iterator;
import java.util.NoSuchElementException;
/*
* The Dequeue is an implementation of Queue that allows for insertions and deletions from both ends
* @author Christian Shadis
* @Version 1.2
*
*/
public class Dequeue extends java.lang.Object {
private int front, rear;
E[] elements;
private static final int INITIAL_CAPACITY = 5;
/*
* Creates an empty Dequeue Running time O(1)
*/
@SuppressWarnings("unchecked")
public Dequeue() {
elements = (E[]) new Object[INITIAL_CAPACITY];
front = 0;
rear = -1;
}
/*
* Creates a larger array containing the same elements in the same order
*
* @post: elements is a larger array and front and rear are reset
*
* Running time O(n)
*/
@SuppressWarnings("unchecked")
private void reallocate() {
int newSize = elements.length + 2;
E[] temp = (E[]) new Object[newSize];
int i = front;
for (int j = 0; j < elements.length; j++) {
temp[j] = elements[i % elements.length];
i++;
}
front = 0;
rear = elements.length - 2;
elements = temp;
}
/*
* Adds an item to the front of the queue
*
* @param anEntry is the item to add to the beginning of the dequeue
*
* @return true
* Running time O(1) NOT counting time for the reallocate method
*/
public boolean addFront(E anEntry) {
if ((rear + 2) % elements.length == front)
reallocate();
if (size() == 0) {
elements[front] = anEntry;
rear++;
} else {
if (front <= 0)
front = elements.length - 1 - front; // moves front to the last element in the array
else
front--;
elements[front] = anEntry;
}
return true;
}
/*
* Adds an item to the rear of the queue
*
* @param anEntry is the item to add to the beginning of the dequeue
*
* @return true
* Running time O(1) NOT counting time for the reallocate method
*/
public boolean addRear(E anEntry) {
if ((rear + 2) % elements.length == front)
reallocate();
rear++;
elements[rear] = anEntry;
return true;
}
/*
* @pre: The dequeue is not empty
*
* @post: the front item on the dequeue has been removed and the queue has one
* fewer element
* Removes and returns the element in the front of the dequeue
*
* @throws NoSuchElementException if the dequeue is empty
*
* @return the element that was in the front position of the dequeue
*/
public E removeFront() {
if (size() == 0)
throw new NoSuchElementException();
else {
E result = elements[front];
front++;
return result;
}
}
/*
* @pre: the dequeue is not empty
*
* @post: the rear item on the queue has been removed and the dequeue is one
* element shorter Removes and returns the rear element in the dequeue
*
* @throws NoSuchElementException if the dequeue is empty
*
* @return the element that was in the rear position of the dequeue
* Running time O(n) since it calls size()
*/
public E removeRear() {
if (size() == 0)
throw new NoSuchElementException();
else {
E result = elements[rear];
if (rear <= 0)
front = elements.length - 1 - rear; // moves rear to the last element in the array
else
rear--;
return result;
}
}
/*
* Returns the object at the front of the dequeue without removal
* @post: dequeue unchanged
*
* @return the object at the front of the dequeue
*
* @throws NoSuchElementException if the dequeue is empty
* Running time O(n) since it calls size()
*/
public E peekFront() {
if (size() == 0)
throw new NoSuchElementException();
else
return elements[front];
}
/*
* Returns the object at the rear of the dequeue without removal
* post: dequeue unchanged
*
* @return the object at the rear of the dequeue
*
* @throws NoSuchElementException if the dequeue is empty
* Running time O(n) since it calls size()
*/
public E peekRear() {
if (size() == 0)
throw new NoSuchElementException();
else
return elements[rear];
}
/*
* Checks if there are any elements in the dequeue
* @post: dequeue unchanged
*
* @return whether it is empty
* Running time O(n) since it calls size().
*/
public boolean empty() {
return (size() == 0);
}
/*
* Checks the size of the dequeue
*
* @pre: none
*
* @post: dequeue unchanged
*
* @return number of elements in the dequeue
* Running time O(n)
*/
public int size() {
if (rear == front - 1 || (rear == elements.length && front == 0))
return 0;
else if (rear >= front)
return (rear - front + 1);
else if (front > rear) {
if (rear < 0)
return 0;
else {
int counter = 0;
for (int j = front; j < elements.length; j++) {
counter++;
}
for (int j = 0; j <= rear; j++) {
counter++;
}
return counter;
}
} else
return 0;
}
/*
* Returns an Iterator object
*/
public java.util.Iterator iterator() {
return new myIterator();
}
private class myIterator implements Iterator {
// Data Fields
// Index of next element
private int index;
// Count of elements accessed so far
private int count = 0;
// Methods
// Constructor
/** Initializes the Iterator object to reference the first dequeue element. */
public myIterator() {
index = front;
}
/** Returns true if there are more elements in the dequeue to access. */
@Override
public boolean hasNext() {
return count < size();
}
/**
* Returns the next element in the dequeue.
*
* @pre index references the next element to access.
* @post index and count are incremented.
* @return The element with subscript index
*/
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
E returnValue = elements[index];
index = (index + 1) % elements.length;
count++;
return returnValue;
}
/** Remove the item accessed by the Iterator object – not implemented. */
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}
Project Details
- Queues, Dequeues
- Circular Array
- Mod function
Python
CS-286 Final Project: Demographics Visualizer
The goal of this project was to use mySQL and Python to analyze student data from the Computer Science Department of Worcester State. Below the code is a link to all outputs from the program.
# Display graphs of Worcester State University's Computer Science Department's data from 2014-2019
# Authors: Christian Shadis, Jaymi-Lyn Souza
# CS-286 Database Design and Applications Final Project
import mysql.connector
import graphs
import queries
# Connect to SQL database
christian_password = "----------"
jaymi_password = "-----------"
christian_port = 3307
jaymi_port = 3306
db = mysql.connector.connect(
host="localhost",
port=christian_port,
# port=jaymi_port,
user="root",
password=christian_password,
# password=jaymi_password,
database="cs_282_finalproject"
)
choice = 0
def main_menu():
main_menu_choice=0
while main_menu_choice != 3:
print('------------------------------------------------')
print('1. View Graphical Representations')
print('2. View Numerical Representations')
print('3. Quit')
print('------------------------------------------------')
main_menu_choice = int(input("Enter your choice: "))
if(main_menu_choice > 0 and main_menu_choice < 4):
if main_menu_choice == 1:
graph_menu()
elif main_menu_choice == 2:
num_menu()
else:
print("Goodbye!")
return
else:
print("Oops! invalid choice, please try again")
main_menu()
def num_menu():
num_menu_choice=0
while num_menu_choice != 3:
print('------------------------------------------------')
print('1. Male vs Female Students (2014-2019)')
print('2. Breakdown by Race/Ethnicity (2014-2019)')
print('3. Back to Main Menu')
print('------------------------------------------------')
num_menu_choice = int(input("Enter your choice: "))
if (num_menu_choice > 0 and num_menu_choice < 4):
if num_menu_choice == 1:
queries.print_gender_numbers()
elif num_menu_choice == 2:
queries.print_race_numbers()
else:
return
else:
print("Oops! Invalid choice, please try again")
num_menu()
def graph_menu():
graph_menu_choice=0
while (graph_menu_choice != 8):
print('------------------------------------------------')
print('1. Line Graph: Gender of CS Students over time')
print('2. Pie Chart: Race of CS Students')
print('3. Pie Chart: Gender of CS Students')
print('4. Bar Graph: Share of CS Major Declarations by Sex')
print('5. Line Graph: African American CS Major Declarations by Year')
print('6. Bar Graph: African American CS Major Declarations by Sex')
print('7. Bar Graph: White men vs Black women in CS Major Declarations: ')
print('8. Return to Main Menu')
print('------------------------------------------------')
graph_menu_choice = int(input("Enter your choice: "))
if (graph_menu_choice>0 and graph_menu_choice < 9):
if graph_menu_choice == 1:
graphs.print_gender_line_chart(db)
if graph_menu_choice == 2:
graphs.print_race_pie_chart(db)
if graph_menu_choice == 3:
graphs.print_gender_pie_chart(db)
if graph_menu_choice == 4:
graphs.print_gender_shares_bar(db)
if graph_menu_choice == 5:
graphs.print_black_line_chart(db)
if graph_menu_choice == 6:
graphs.print_black_gender_bar(db)
if graph_menu_choice == 7:
graphs.print_black_women_white_men_bar(db)
if graph_menu_choice == 8:
return
else:
print("Oops! Invalid choice, please try again")
graph_menu()
#Program starts running here
main_menu()
exit()
# Display graphs of Worcester State University's Computer Science Department's data from 2014-2019
# Authors: Christian Shadis, Jaymi-Lyn Souza
# CS-286 Database Design and Applications Final Project
import matplotlib.pyplot as plt
import numpy as np
def print_race_pie_chart(db):
mycursor = db.cursor()
race_counts = []
for x in range(1, 12):# Run queries for each race
query = "SELECT COUNT(*) FROM student WHERE race=" + str(x)
mycursor.execute(query)
result = mycursor.fetchone()
race_counts.append(result[0])
# advised to consolidate indeces 1 and 7
race_counts[1] = race_counts[1] + race_counts[7]
# delete index 7
for i in range(8, 11):
race_counts[i - 1] = race_counts[i]
race_counts.pop()
# deleting index 3 - an index was skipped in the original data set
for i in range(4, 10):
race_counts[i - 1] = race_counts[i]
race_counts.pop()
legend_labels = ['Non-resident Alien', 'African American', 'American Indian or Alaskan Native',
'Hispanic or Latino', 'White', 'Unknown', 'Multiracial',
'Asian', 'Native Hawaiian or Pacific Islander']
total = 0# total number of students
for x in race_counts:
total = total + x
percentages = [(x / total) * 100 for x in race_counts]
explode = (0, 0.15, 0, 0, 0, 0, 0, 0, 0) # emphasize African-American Representation
colors = ['#FFC0CB', '#9932CC', '#BFFF00', '#900D09', '#0288D1', '#3b4b21', '#00ffff', '#ff8b3d', '#000000']
# just some nice colors
ax1 = plt.subplot()
patches, texts = ax1.pie(percentages, labeldistance=1.3, colors=colors, explode=explode, shadow=True,
counterclock=False,
startangle=45)
ax1.axis('equal')
plt.legend(patches, ['%s, %1.1f %%' % (l, s) for l, s in zip(legend_labels, percentages)], loc = "center right", \
bbox_transform= plt.gcf().transFigure,
bbox_to_anchor=(1, 0.5), fontsize=10)
plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45)
ax1.set_title("CS Dept Enrollment by Race,\n 2014-2019")
plt.show()
def print_gender_pie_chart(db):
mycursor = db.cursor() #instantiate cursor
mycursor.execute("SELECT COUNT(*) FROM student WHERE sex=2")#Select all women
queryresult = mycursor.fetchone()
women = queryresult[0]
mycursor.execute("SELECT COUNT(*) FROM student WHERE sex=1")#Select all men
queryresult = mycursor.fetchone()
men = queryresult[0]
labels = ['Men', 'Women']
percentages = [(men/(men+women))*100, (women/(men+women))*100]
explode = (0, 0.1)
ax1 = plt.subplot()
patches, texts, autotexts = ax1.pie(
percentages,
labeldistance=1.1,
colors=["#4B878BFF","#D01C1FFF"],
explode=explode,
shadow=True,
counterclock=False,
startangle=45,
labels=labels,
autopct='%1.0f%%',
)
ax1.axis('equal')
plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45)
plt.show()
def print_gender_line_chart(db):
dbcursor = db.cursor()
# create variables to store men/women from 2014
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2014 AND sex=2")
women_14 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2014 AND sex=1")
men_14=(dbcursor.fetchone())[0]
# create variables to store men/women from 2015
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2015 AND sex=2")
women_15 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2015 AND sex=1")
men_15 = (dbcursor.fetchone())[0]
# create variables to store men/women from 2016
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2016 AND sex=2")
women_16 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2016 AND sex=1")
men_16 = (dbcursor.fetchone())[0]
# create variables to store men/women from 2017
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2017 AND sex=2")
women_17 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2017 AND sex=1")
men_17 = (dbcursor.fetchone())[0]
# create variables to store men/women from 2018
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2018 AND sex=2")
women_18 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2018 AND sex=1")
men_18 = (dbcursor.fetchone())[0]
# create variables to store men/women from 2019
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2019 AND sex=2")
women_19 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2019 AND sex=1")
men_19 = (dbcursor.fetchone())[0]
# create lists of values
men_counts_by_year=[men_14,men_15,men_16,men_17,men_18,men_19]
women_counts_by_year = [women_14, women_15, women_16, women_17, women_18, women_19]
years=[2014,2015,2016,2017,2018,2019]
ax1 = plt.subplot(1,1,1)
plt.plot(years, women_counts_by_year, marker="o", color="#DB5A42")
plt.plot(years, men_counts_by_year, marker="o", color="#3F3847")
plt.legend(labels=['Women', 'Men'],
loc=10,
shadow=True,
#facecolor="#4C5B61",
labelcolor=("#000000"))
plt.xlabel("Year")
plt.ylabel("Number of CS Major Declarations")
ax1.set_facecolor("#cecfc7")
ax1.set_xticks(years)
plt.show()
def print_gender_shares_bar(db):
dbcursor=db.cursor()
labels=[2014,2015,2016,2017,2018,2019]
def get_pct(sex, year):
queryinput = "SELECT COUNT(*) FROM student WHERE sex=1 AND academicYear=" + str(year)
dbcursor.execute(queryinput)
num_men = dbcursor.fetchone()[0]
queryinput = "SELECT COUNT(*) FROM student WHERE sex=2 AND academicYear=" + str(year)
dbcursor.execute(queryinput)
num_women = dbcursor.fetchone()[0]
total_people = num_women + num_men
if(sex==1):
return num_men / total_people
else:
return num_women/total_people
men_pcts=[get_pct(1, year) for year in labels]
men_pcts=[temp*100 for temp in men_pcts]
men_pcts=[round(temp,2) for temp in men_pcts]
women_pcts=[get_pct(2, year) for year in labels]
women_pcts=[temp*100 for temp in women_pcts]
women_pcts=[round(temp,2) for temp in women_pcts]
x=np.arange(len(labels))
width=0.35
fig1, ax1=plt.subplots()
men_rects=ax1.bar(x-width/2, men_pcts, width, label="Male", color="#3F3847")
women_rects=ax1.bar(x+width/2, women_pcts, width, label="Female", color="#DB5A42")
ax1.set_ylabel("Percent share")
ax1.set_xlabel("Year")
ax1.set_title("Share of enrollment by sex")
ax1.set_xticks(x)
ax1.set_xticklabels(labels)
ax1.set_facecolor("#cecfc7")
ax1.legend(loc='lower left', bbox_to_anchor= (0.0, 1.001))
plt.show()
def print_black_line_chart(db):
dbcursor = db.cursor()
#2014
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2014 AND race=2")
black_students_2014 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2014")
total_2014=(dbcursor.fetchone())[0]
# 2015
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2015 AND race=2")
black_students_2015 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2015")
total_2015 = (dbcursor.fetchone())[0]
# 2016
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2016 AND race=2")
black_students_2016 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2016")
total_2016 = (dbcursor.fetchone())[0]
# 2017
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2017 AND race=2")
black_students_2017 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2017")
total_2017 = (dbcursor.fetchone())[0]
# 2018
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2018 AND race=2")
black_students_2018 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2018")
total_2018 = (dbcursor.fetchone())[0]
# 2019
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2019 AND race=2")
black_students_2019 = (dbcursor.fetchone())[0]
dbcursor.execute("SELECT COUNT(*) FROM student WHERE academicYear=2019")
total_2019 = (dbcursor.fetchone())[0]
# create lists of values
black_student_counts_by_year = [
black_students_2014,
black_students_2015,
black_students_2016,
black_students_2017,
black_students_2018,
black_students_2019
]
total_counts_by_year = [total_2014,total_2015,total_2016,total_2017, total_2018, total_2019]
black_percentage=[black/total for (black, total) in zip(black_student_counts_by_year, total_counts_by_year)]
black_percentage=[num*100 for num in black_percentage]#convert to %
black_percentage=[round(temp, 2) for temp in black_percentage]#round percentage
years = [2014, 2015, 2016, 2017, 2018, 2019]
ax1 = plt.subplot(1, 1, 1)
plt.plot(years, black_percentage, marker="o", color="#DB5A42")
plt.xlabel("Year")
plt.ylabel("Share of enrollment (%)")
ax1.set_facecolor("#cecfc7")
ax1.set_xticks(years)
ax1.set_title("Enrollment share of Black Students per year")
plt.show()
def print_black_gender_bar(db):
dbcursor = db.cursor()
labels = [2014, 2015, 2016, 2017, 2018, 2019]
def get_count(sex, year):
queryinput = "SELECT COUNT(*) FROM student WHERE sex=1 AND academicYear=" + str(year) + " AND race=2" #all black men
dbcursor.execute(queryinput)
num_men = dbcursor.fetchone()[0]
queryinput = "SELECT COUNT(*) FROM student WHERE sex=2 AND academicYear=" + str(year) + " AND race=2" #all black women
dbcursor.execute(queryinput)
num_women = dbcursor.fetchone()[0]
if(sex==1):
return num_men
else:
return num_women
men_counts = [get_count(1, year) for year in labels]
women_counts = [get_count(2, year) for year in labels]
x = np.arange(len(labels))
width = 0.35
fig1, ax1 = plt.subplots()
men_rects = ax1.bar(x - width / 2, men_counts, width, label="Male", color="#3F3847")
women_rects = ax1.bar(x + width / 2, women_counts, width, label="Female", color="#DB5A42")
ax1.set_ylabel("Students")
ax1.set_xlabel("Year")
ax1.set_title("Number of African American Students by Sex")
ax1.set_xticks(x)
ax1.set_xticklabels(labels)
ax1.set_facecolor("#cecfc7")
ax1.legend(loc='upper left')
def autolabel(rects, color):
"""
Attach a text label above each bar displaying its height
"""
for rect in rects:
height = rect.get_height()
ax1.text(rect.get_x() + rect.get_width() / 2., .005 + height,
'%d' % int(height),
ha='center', va='bottom',
color=color)
autolabel(men_rects, "#3F3847")
autolabel(women_rects, "#DB5A42")
plt.show()
def print_black_women_white_men_bar(db):
dbcursor = db.cursor()
labels = [2014, 2015, 2016, 2017, 2018, 2019]
def get_count(sex, year):
queryinput = "SELECT COUNT(*) FROM student WHERE sex=1 AND academicYear=" + str(
year) + " AND race=6" # all white men
dbcursor.execute(queryinput)
num_men = dbcursor.fetchone()[0]
queryinput = "SELECT COUNT(*) FROM student WHERE sex=2 AND academicYear=" + str(
year) + " AND race=2" # all black women
dbcursor.execute(queryinput)
num_women = dbcursor.fetchone()[0]
if (sex == 1):
return num_men
else:
return num_women
men_counts = [get_count(1, year) for year in labels]
women_counts = [get_count(2, year) for year in labels]
x = np.arange(len(labels))
width = 0.35
fig1, ax1 = plt.subplots()
men_rects = ax1.bar(x - width / 2, men_counts, width, label="Male", color="#3F3847")
women_rects = ax1.bar(x + width / 2, women_counts, width, label="Female", color="#DB5A42")
ax1.set_ylabel("Students")
ax1.set_xlabel("Year")
ax1.set_title("White Men \nvs Black Women")
ax1.set_xticks(x)
ax1.set_xticklabels(labels)
ax1.set_facecolor("#cecfc7")
ax1.legend(loc='lower left', labels=['White Men', 'Black Women'], bbox_to_anchor=(0.0, 1.001))
def autolabel(rects, color):
"""
Attach a text label above each bar displaying its height
"""
for rect in rects:
height = rect.get_height()
ax1.text(rect.get_x() + rect.get_width() / 2., .005 + height,
'%d' % int(height),
ha='center', va='bottom',
color=color)
autolabel(men_rects, "#3F3847")
autolabel(women_rects, "#DB5A42")
plt.show()
# Display graphs of Worcester State University's Computer Science Department's data from 2014-2019
# Authors: Christian Shadis, Jaymi-Lyn Souza
# CS-286 Database Design and Applications Final Project
import pandas as pd
from sqlalchemy import create_engine
import pymysql
christian_password="---------"
christian_port="3307"
jaymi_password="---------------"
jaymi_port="3306"
#IMPORTS MYSQL TABLE INTO PANDAS
db_connection_str = "mysql+pymysql://root:"+christian_password+"@127.0.0.1:"+christian_port+"/cs_282_finalproject"
# db_connection_str = "mysql+pymysql://root:"+jaymi_password+"@127.0.0.1:"+jaymi_port+"/cs_282_finalproject"
db_connection = create_engine(db_connection_str)
df = pd.read_sql('SELECT * FROM STUDENT', con=db_connection)
# .value_counts() parses the data and counts up the frequency of values in the specified column
# .loc[] chooses just one of the occurrences
def print_gender_numbers():
gender_numbers = df['sex'].value_counts()
male = str(gender_numbers.loc[1])
female = str(gender_numbers.loc[2])
print ('The total number of CS students of each gender from 2014-2019 is: \n Male: ' + male + ' \n Female: ' + female)
#there are 0 instances of some of the cases, which is why they are commented out
def print_race_numbers():
race_numbers = df['race'].value_counts()
nra = str(race_numbers.loc[1])
black = str(race_numbers.loc[2])
# indigenous = str(race_numbers.loc[3])
hispanic_latino = str(race_numbers.loc[5])
white = str(race_numbers.loc[6])
unknown = str(race_numbers.loc[7])
multiple = str(race_numbers.loc[9])
asian = str(race_numbers.loc[10])
# native_hawaiian = str(race_numbers.loc[11])
print('The total number of CS students of each race from 2014-2019 is: \nWhite: ' + white)
print("Black: " + black)
print('Hispanic/Latinx: ' + hispanic_latino)
# print('American Indian or Alaskan Native: ' + indigenous)
print('Asian: ' + asian)
# print('Native Hawaiian or other Pacific Islander: ' + native_hawaiian)
print('Multiple races/ethnicities: \t' + multiple)
print('Unknown: ' + unknown)
print('Non-Resident Alien: ' + nra)
Project Details
- Multilevel interactive text-based user menu
- MySQL database connection
- List Comprehension
- Matplotlib
- Pandas
- Loops, Conditionals
CS-135 Final Project: Command-Line Tax Calculator
#Christian Shadis
#Final Project - due 12/18/2018
#Computes figures pertaining to a user's tax information based on 2017 data
filing_choice = 0
while filing_choice != 5:
#Menu
print('**************************')
print('To get started, are you...')
print('1. Single')
print('2. Married, filing jointly')
print('3. Head of Household')
print('4. Married, filing seperately')
print('5. Quit the program')
print('**************************')
print()
#user input for menu
filing_choice = int(input('Enter your choice: '))
#prevents invalid entry
if filing_choice > 5:
filing_choice = int(input('Please enter a valid selection: '))
#single calculation
if filing_choice == 1:
print()
print('You selected: Filing Single')
taxable_income = float(input('Please enter your gross pay for the year: '))
if taxable_income < 9325:
tax_amount = taxable_income / 10
tax_rate = '10%'
tax_method = '10% of the excess over $0'
elif taxable_income < 37950:
tax_amount = 932.50 + ((taxable_income - 9325)*0.15)
tax_rate= '15%'
tax_method = '$932.50 plus 15% of the excess over $9,325'
elif taxable_income < 91900:
tax_amount = 5226.25 + ((taxable_income - 37950)/4)
tax_rate = '25%'
tax_method = '$5,226.50 plus 25% of the excess over $37,950'
elif taxable_income < 190650:
tax_amount = 18713.75 + (.28 * (taxable_income - 91900))
tax_rate = '28%'
tax_method = '$18,713.75 plus 28% of the excess over $91,900'
elif taxable_income < 416700:
tax_amount = 46643.75 + (.33 * (taxable_income - 191650)) #seems like a mistake - should be 190650, but the website says 191650
tax_rate = '33%'
tax_method = '$46,643.75 plus 33% of the excess over $191,650'
elif taxable_income < 418400:
tax_amount = 120910.25 + (.35 * (taxable_income - 416700))
tax_rate = '35%'
tax_method = '$120,910.25 plus 35% of the excess over $416,700'
else:
tax_amount = 121505.25 + (.396 * (taxable_income - 418400))
tax_rate = '39.6%'
tax_method = '$121,505.25 plus 39.6% of the excess over $418,400'
#Married, jointly calculation
if filing_choice == 2:
print()
print('You selected: Married, Filing Jointly')
taxable_income = float(input('Please enter your gross pay for the year: '))
if taxable_income < 18650:
tax_amount = taxable_income / 10
tax_rate = '10%'
tax_method = '10% of the excess over $0'
elif taxable_income < 75900:
tax_amount = 1855 + ((taxable_income - 18550)*0.15)
tax_rate= '15%'
tax_method = '$1,855 plus 15% of the excess over $18,550'
elif taxable_income < 153100:
tax_amount = 10368 + ((taxable_income - 75300)/4)
tax_rate = '25%'
tax_method = '$10,368 plus 25% of the excess over $75,300'
elif taxable_income < 233350:
tax_amount = 29518 + (.28 * (taxable_income - 151900))
tax_rate = '28%'
tax_method = '$29,518 plus 28% of the excess over $151,900'
elif taxable_income < 416700:
tax_amount = 51792 + (.33 * (taxable_income - 231450))
tax_rate = '33%'
tax_method = '$51,792 plus 33% of the excess over $231,450'
elif taxable_income < 470700:
tax_amount = 111819 + (.35 * (taxable_income - 413350))
tax_rate = '35%'
tax_method = '$111,819 plus 35% of the excess over $413,350'
else:
tax_amount = 130579 + (.396 * (taxable_income - 466950))
tax_rate = '39.6%'
tax_method = '$130,579 plus 39.6% of the excess over $466,950'
#Head of Household Calculation
if filing_choice == 3:
print()
print('You selected: Head of Household')
taxable_income = float(input('Please enter your gross pay for the year: '))
if taxable_income < 13350:
tax_amount = taxable_income / 10
tax_rate = '10%'
tax_method = '10% of the excess over $0'
elif taxable_income < 50800:
tax_amount = 1335 + ((taxable_income - 13350)*0.15)
tax_rate= '15%'
tax_method = '$1,335 plus 15% of the excess over $13,350'
elif taxable_income < 131200:
tax_amount = 6952.50 + ((taxable_income - 50800)/4)
tax_rate = '25%'
tax_method = '$6,952.50 plus 25% of the excess over $50,800'
elif taxable_income < 212500:
tax_amount = 27052.50 + (.28 * (taxable_income - 131200))
tax_rate = '28%'
tax_method = '$27,052.50 plus 28% of the excess over $131,200'
elif taxable_income < 416700:
tax_amount = 49816.50 + (.33 * (taxable_income - 212500))
tax_rate = '33%'
tax_method = '$49,816.50 plus 33% of the excess over $212,500'
elif taxable_income < 444500:
tax_amount = 117202.50 + (.35 * (taxable_income - 416701))
tax_rate = '35%'
tax_method = '$117,202.50 plus 35% of the excess over $413,350'
else:
tax_amount = 126950 + (.396 * (taxable_income - 444550))
tax_rate = '39.6%'
tax_method = '$126,950 plus 39.6% of the excess over $444,550'
#Married, Filing Seperately Calculation
if filing_choice == 4:
print()
print('You selected: Married, Filing Seperately')
taxable_income = float(input('Please enter your gross pay for the year: '))
if taxable_income < 9325:
tax_amount = taxable_income / 10
tax_rate = '10%'
tax_method = '10% of the excess over $0'
elif taxable_income < 37950:
tax_amount = 932.50 + ((taxable_income - 9325)*0.15)
tax_rate= '15%'
tax_method = '$932.50 plus 15% of the excess over $9,325'
elif taxable_income < 76550:
tax_amount = 5226.25 + ((taxable_income - 37950)/4)
tax_rate = '25%'
tax_method = '$5,226.25 plus 25% of the excess over $37,950'
elif taxable_income < 116675:
tax_amount = 14876.25 + (.28 * (taxable_income - 76550))
tax_rate = '28%'
tax_method = '$14,876.25 plus 28% of the excess over $76,550'
elif taxable_income < 208350:
tax_amount = 26111.25 + (.33 * (taxable_income - 116675))
tax_rate = '33%'
tax_method = '$26,111.25 plus 33% of the excess over $116,675'
elif taxable_income < 235350:
tax_amount = 56364 + (.35 * (taxable_income - 208350))
tax_rate = '35%'
tax_method = '$56,364 plus 35% of the excess over $208,350'
else:
tax_amount = 65814 + (.396 * (taxable_income - 235350))
tax_rate = '39.6%'
tax_method = '$65,814 plus 39.6% of the excess over $235,350'
#inner menu
if filing_choice != 5:
inner_menu_choice = 0
print('_____________________________')
print('What would you like to know?')
print('1. Tax Rate')
print('2. The method to calculate your taxes')
print('3. Your total tax responsibility')
print('4. Your net income')
print('5. All of the Above')
print('_____________________________')
print()
print()
inner_menu_choice = int(input('Enter your choice here: '))
if inner_menu_choice == 1:
print('Your tax rate is: %s' %(tax_rate))
print('---------------------------------------------------')
elif inner_menu_choice == 2:
print('Your tax rate is calculated as follows: %s' %(tax_method))
print('---------------------------------------------------')
elif inner_menu_choice == 3:
print('Your total tax responsibility is as follows: $%.2f' %(tax_amount))
print('---------------------------------------------------')
elif inner_menu_choice == 4:
net_income = taxable_income - tax_amount
print('Your net income is: $%.2f' %(net_income))
print('---------------------------------------------------')
elif inner_menu_choice == 5:
net_income = taxable_income - tax_amount
print()
print('Your tax rate is: %s' %(tax_rate))
print('Your tax rate is calculated as follows: %s' %(tax_method))
print('Your total tax responsibility is as follows: $%.2f' %(tax_amount))
print('Your net income is: $%.2f' %(net_income))
print('---------------------------------------------------')
else:
inner_menu_choice = int(input('Please enter a valid option: '))