HomeBlog
WASHINGTON & JEFFERSON COLLEGE

First Higher-Ed.

PHYSICSCHEMMATHCOMPUTERS

MY COURSEWORKMY JAVA CODEMY PHOTOGRAPHYMY PYTHON CODE
COURSEWORK

What my education entails.

Courses and What I Learned

CIS 220 and CIS 320

all 2016 and Fall 2018,
Dr. Holland-Minkley

Object Oriented Programming (Java) and Data Structures

In these classes I learned the basics of object-oriented programming as well as more advanced topics such as data structures. I learned when to use certain data structures such as arrays, linked lists, and trees. Additionally, I learned about ML and Artificial Intelligence and methods such as kNN (k Nearest Neighbors) and decision trees. Lastly, we learned different ways to implement Abstract Data Types (ADTs).

SEE MY JAVA CODE

CIS 341

Fall 2018,
Dr. Hallenbeck

Numerical Computation (Python)

In this course, I learned how to apply my computer knowledge and skills to physics and mathematical equations such as coding a derivative, integral, differential Equation, and approximation calculators. In addition, I learned about Python graphics (making plots, histograms, etc.) and how to code cellular automata.

SEE MY PYTHON CODE

PHY 322

Fall 2018,
Dr. McCracken

Electronics (Intro to EE)

This course was an introductory course into electronics. We learned about DC circuits, AC circuits, transformers, op amps, integrated circuits, and used calculus to analyze them as well as Kirchhoff's laws. Below is a video of the final project which was a baby 10 synthesizer with a VCO (Voltage Controlled Oscillator).

PHY 250

Spring 2018, Dr. McCracken

Math Methods for Engineers

In this class, we learned a lot of ways to apply our knowledge of Mathematics in fields such as calculus, integration (line integrals, area integrals, volume integrals), derivatives, matricies, and differential equations. Additionally, this course had a lab in which we programmed in Python to solve some physical/mathematical problems. This was a class about linear algebra as well as differential equations.

CIS 301

Fall 2018, Dr. Hannon

Human-Computer Interaction

In this course we learned about designing a product through kick-off meetings, user research, shareholder input, and the cooper method. Although we did not go over Agile or Scrum meetings, I have learned a concept about these topics. For the final in this class we had to produce a prototype of what we designed for the better-part of half the semester. Click here to see the protoype in Axure (web-browser based). We learned that designing a product in 4 weeks is not usually do-able.

MTH 151, MTH 152, and MTH 208

Fall 2016, Spring 2017, and Fall 2017

Calculus I, II, and III

In these classes we first learned the basics of calculus and progress to much more intense topics. Calculus I covered basic integrals, derivatives, and related rates problems. Calculus two covered more about series and whether they converge/diverge. Then Calculus three covered 3-dimensional calculus.

CHM 160 (and CHM 260 at CCAC)

Fall 2017 (and Summer 2017)

Organic and Inorganic Chemistry

CHM260 at W&J College is the general (inorganic) chemistry course. CHM160 at W&J is the organic chemistry course where the structure of atoms is more investigated.

CIS 271 and CIS 365

Spring 2018

Digital Media and Digital Film

These courses emphasized the importance of digital media such as photography, videotagraphy, design, and social media usage.

SEE SOME OF MY WORK
JAVA CODE

What I Have Java Coded.

CIS 320

k Nearest Neighbors Machine Learning (kNN)

Taught by and aided by Dr. Holland-Minkley

Using kNN to Predict Bike Sales (Click Here to Download)

Code Preview
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

// DataPoint - object class with instance data for each column in source data
// file, a constructor, a display method, getters, and a method for computing
// distance metric
class DataPoint {
	private String datetime;
	private int season, holiday, workingday, weather, humidity, count;
	private int hour; //time of day difference
	private double temp, atemp,	windspeed;
	
	public DataPoint(String d, int s, int ho, int wD, int we, double t, double aT,
			int hu, double wi, int c) {
		datetime = d;
		season = s;	// categorical
		holiday = ho;	// categorical
		workingday = wD;	// categorical
		weather = we;	// categorical
		temp = t;	// numerical
		atemp = aT;	// numerical
		humidity = hu;	// numerical
		windspeed = wi;	// numerical
		count = c;
		
		String hr = d.split(" ")[1]; //Split at space,
		hr = hr.split(":")[0]; //Split at x:00, we want x which is index 0
		hour = Integer.parseInt(hr); //Convert string to int and store in hours
	}
	
	public String getDatetime() {return datetime;}
	public int getSeason() {return season;}
	public int getHoliday() {return holiday;}
	public int getWorkingDay() {return workingday;}
	public int getWeather() {return weather;}
	public int getHumidity() {return humidity;}
	public int getCount() {return count;}
	public double getTemp() {return temp;}
	public double getAtemp() {return atemp;}
	public double getWindspeed() {return windspeed;}
	public int getHour() { return hour;} //Get the hour of day
	
	public double distance(DataPoint day2) {
		// CODE REQUIRED HERE FOR CALCULATING DISTANCE BETWEEN TWO DATA POINTS
		int diff1, diff2, diff3, diff4, diff5; //Season, holiday, workingday, weather, humid
		double diff6, diff7, diff8; //temp, actual temp, windspeed
		int diff9; //time of day
		
		//NOTE: The squaring in the actual equation will handle negatives
		if (this.getSeason() != day2.getSeason()) { //Season is different
			diff1 = 1; //So increase their distance apart
		} else { // If the season is the same
			diff1 = 0; //Do not increase their distance apart
		}
		diff2 = Math.abs(this.getHoliday() - day2.getHoliday()); //get difference which is
		diff3 = Math.abs(this.getWorkingDay() - day2.getWorkingDay()); //not greater than 1
		if (this.getWeather() != day2.getWeather()) { //not same
			diff4 = 1; //increase distance apart
		} else { //They are equal
			diff4 = 0; //Their distance apart shall not be increased
		}
		diff5 = this.getHumidity() - day2.getHumidity();
		diff6 = this.getTemp() - day2.getTemp();
		diff7 = this.getAtemp() - day2.getAtemp();
		diff8 = this.getWindspeed() - day2.getWindspeed();
		
		//Calculate difference between hours of day
		diff9 = Math.abs(this.getHour() - day2.getHour());
		
		//The largest difference in hours should be 12...
		if (diff9 > 12) { //then we have to fix the time diff
			diff9 = Math.abs((24-day2.getHour()) + this.getHour());
		}
		//System.out.println("This: "+this.getDatetime()+", Comp:"+day2.getDatetime()
			//+", Diff: "+diff9);
		
		return Math.sqrt(Math.pow(diff1, 2) + Math.pow(diff2, 2) +
					     Math.pow(diff3, 2) + Math.pow(diff4, 2) +
					     Math.pow(diff5, 2) + Math.pow(diff6, 2) +
					     Math.pow(diff7, 2) + Math.pow(diff8, 2) +
					     Math.pow(diff9,  2));
	}
	
	/************************************************
	 * Distance without considering hour:
	 */
		/*public double distance(DataPoint day2) {
		// CODE REQUIRED HERE FOR CALCULATING DISTANCE BETWEEN TWO DATA POINTS
		int diff1, diff2, diff3, diff4, diff5;
		double diff6, diff7, diff8;
		
		//NOTE: The squaring in the actual equation will handle negatives
		if (this.getSeason() != day2.getSeason()) { //Season is different
			diff1 = 1; //So increase their distance apart
		} else { // If the season is the same
			diff1 = 0; //Do not increase their distance apart
		}
		diff2 = Math.abs(this.getHoliday() - day2.getHoliday()); //get difference which is
		diff3 = Math.abs(this.getWorkingDay() - day2.getWorkingDay()); //not greater than 1
		if (this.getWeather() != day2.getWeather()) { //not same
			diff4 = 1; //increase distance apart
		} else { //They are equal
			diff4 = 0; //Their distance apart shall not be increased
		}
		diff5 = this.getHumidity() - day2.getHumidity();
		diff6 = this.getTemp() - day2.getTemp();
		diff7 = this.getAtemp() - day2.getAtemp();
		diff8 = this.getWindspeed() - day2.getWindspeed();
		
		
		return Math.sqrt(Math.pow(diff1, 2) + Math.pow(diff2, 2) +
					     Math.pow(diff3, 2) + Math.pow(diff4, 2) +
					     Math.pow(diff5, 2) + Math.pow(diff6, 2) +
					     Math.pow(diff7, 2) + Math.pow(diff8, 2));
	}
	*/
	 
	
	public String toString() {
		return datetime + ": " + count + " rentals";
	}
}

// Link - a single link object with its data being a DataPoint object
class Link {
	public DataPoint data;              // data item (key)
	public Link next;              // next link in list

	public Link(DataPoint d) {
		data = d;
		next = null;
	}
		
	public void displayLink() {
		System.out.print(data);
	}
}

// DataList - a collection of DataPoints stored in a Linked List arrangement
// Supports insertion of DataPoints into the list, a kNN list processing
// method operation that determines for a DataPoint and a value of k what the
// predicted number of bikes needed for the given DataPoint, and a runTest
// method that takes in a list of DataPoints with known bike demand and
// computes the total sum of squared error of kNN against the list of DataPoints
// using the given k.
// Note that delete and find operations are not required.
class DataList {
	private Link first;
	private int numItems;

	public DataList() {
		first = null;
		numItems = 0;
	}
	
	public int getNum() {return numItems;}

	// insert DataPoint in list in constant time
	public void insert(DataPoint d) {
		Link newLink = new Link(d);
		newLink.next = first;
		first = newLink;
		numItems ++;
   }

   // calculate kNN prediction of number of bikes needed on newDay considering
   // given k number of nearest neighbors
	
	/****************************************
	 * The kNN below, keeps the array sorted
	 *  */
	
	/*public int kNN(DataPoint newDay, int k) {
		DataPoint kDataPoints[] = new DataPoint[k];
		Double kDistances[] = new Double[k];
		Link temp = first;
		long time = System.nanoTime();
		
		for (int i = 0; i < numItems; i++) {
			double dist = newDay.distance(temp.data);
			//System.out.println("At hand: "+dist);
			if (i < k) { //Then the array is not filled because we must insert
				kDataPoints[i] = newDay;  //Up until i = k, then array is filled
				kDistances[i] = dist;
				
				//Need to sort initially,
				for (int sort = 0; sort < i-1; sort++) {
					if (kDistances[sort] > kDistances[sort+1]) {
						//Then swap
						double tempD = kDistances[sort+1];
						kDistances[sort+1] = kDistances[sort];
						kDistances[sort] = tempD;
					}
				} //End of sort loop, sorted :)
				
				//Note on sorting:
				//Highest index means highest distance
			} else { //We must see if our new distance is smaller than any inside
				int where = 0;
				boolean found = false;
				for (int j = 0; j < kDataPoints.length; j++) {
					if (kDistances[j] > dist) { //The current dist is smaller
						//So, we are going to have to bump everything up
						found = true;
						where = j;
						for (int sort = k-2; sort >= j; sort--) {
							kDistances[sort+1] = kDistances[sort];
							kDataPoints[sort+1] = kDataPoints[sort];
						}
						break;
					} //else continue through loop
				}
				if (found) {
					kDistances[where] = dist;
					kDataPoints[where] = temp.data;
				}
			}
			//System.out.println("\n New:");
			//for (int show = 0; show < k; show++) {
			//	System.out.println(kDistances[show]);
			//}
			temp = temp.next;
		}
		
		double pred = 0;
		for (int i = 0; i numItems) { //There are not enough neighbors to do this algorithm
			return 0;
		}
		DataPoint kDataPoints[] = new DataPoint[k];
		Double kDistances[] = new Double[k];
		
		//Starts at the first link, after each iteration it updates to next
		Link temp = first;
		//long time = System.nanoTime();

		for (int i = 0; i < numItems; i++) {
			double dist = newDay.distance(temp.data); //Get distance between two points
			//System.out.println("New Distance at hand: "+dist);
			if (i < k) { //Then the array is not filled because we must insert
				kDataPoints[i] = temp.data;  //Up until i = k, then array is filled
				kDistances[i] = dist; //Must assign distance too. Don't want to lose
									  //it, additionally, these two arrays align
									  //when describing the same point and distance
			} else { //We must see if our new distance is smaller than any inside
				
				int max = 0;
				boolean found = false;
				
				for (int j = 0; j < kDataPoints.length; j++) {
					if (kDistances[j] > dist) { //The current dist is smaller, replace
						found = true; //True, the dist and DataPoint should be inserted
						if (kDistances[j] > kDistances[max]) {
							max = j;
						}
					} //else continue through loop
				}
				if (found) { //only if a different maximum was found
					kDataPoints[max] = temp.data;
					kDistances[max] = dist;
				}
			}
			temp = temp.next;
		}
		
		
		//Now let's get the predicted count
		double pred = 0;
		for (int i = 0; imax)
				max = currDiff;
			
			
			//Info output:
			String currDate = curr.data.getDatetime();
			int actualCount = curr.data.getCount();
			if (DISP)
				System.out.println(currDate+": actual bikes: "+actualCount
						+" Predicted count: "+pred+". Square Difference: "+currDiff);
			
			curr = curr.next;
		}
		
		
		//System.out.println("Total Sum of Squared Differences: "+difference);
		double avg = (double)difference/(double)numItems; //get square average by dividing by number
										  //of items considered
		//System.out.println("Average Sum of Squared Differences: "+avg);
		//System.out.println("Maximum square difference found: "+max+", Min: "+min);
		
		
		return difference;
	}
	
	public void displayList() {
		System.out.print("List (first-->last): ");
		Link current = first;
		while(current != null) {
			current.displayLink();
			System.out.println("\t");
			current = current.next;
		}
	}
}

public class BikeDemandkNN {
	public static void main (String[] args) throws IOException {
		int k = 5; //Starting k value
		int checkks = 5; //ending k value
		int bestk = -1; //k with lowest squared difference
		long bestSquared = -1; //best squared value
		long errors[] = new long[checkks-k+1]; //used to make copying and pasting
											  //data easier, for square diffs
		
		final boolean DISP_TIME_ALL = true; //Toggles display of all times at once
		final boolean DISP_ERROR_ALL = true; //Toggles display of all sums at once
		long times[] = new long[checkks-k+1]; // Same as above, but for times
			//System.out.println("Time through: "+(i+1));
			Scanner fileScan = new Scanner(new File("sharingData.csv"));
			fileScan.nextLine();	// read past header line
			
			DataList training = new DataList();
			DataList testing = new DataList();
			
			Random gen = new Random();
			
			while (fileScan.hasNext()){
				String rowData = fileScan.nextLine();
				Scanner dayScan = new Scanner(rowData);
				dayScan.useDelimiter(",");
				
				String datetime;
				int season, holiday, workingday, weather, humidity, count;
				double temp, atemp,	windspeed;
				
				datetime = dayScan.next();
				season = dayScan.nextInt();
				holiday = dayScan.nextInt();
				workingday = dayScan.nextInt();
				weather = dayScan.nextInt();
				temp = dayScan.nextDouble();
				atemp = dayScan.nextDouble();
				humidity = dayScan.nextInt();
				windspeed = dayScan.nextDouble();
				count = dayScan.nextInt();
				
				DataPoint tempDay = new DataPoint(datetime, season, holiday, workingday,
						weather, temp, atemp, humidity, windspeed, count);
	
				
				// once insertion has been tested, the following code inserts
				// data items into the testing list with 1 in 100 probability
				if (gen.nextInt(100)==0) {
					testing.insert(tempDay);
				} else {
					training.insert(tempDay);
				}
				
	
				
				dayScan.close();
			}
			fileScan.close();
	
			System.out.println(training.getNum() + " items inserted in training list");
			System.out.println(testing.getNum() + " items inserted in testing list");
	
			
			// method call to compare held out test data against set of training
			// data using a k of 5
			int i = 0; // i does not necessarily equal k.
			while (k <= checkks) {
				long time = System.nanoTime(); //starting time
				long error = testing.runTest(training, k);
				//System.out.println("Total sum of squared error: " + error +"\n");
				time = (System.nanoTime() - time); //time to run
				
				//error = error/testing.getNum();
				if (bestSquared == -1 || bestSquared > error) {
					bestSquared = error;
					bestk = k;
				}
				System.out.println("K Value: "+k+":"); //Displays the time per run
				System.out.println("Square Diff: "+error); //prints out the square diff
				System.out.println("Time (ns): "+time+"\n");
				errors[i] = error;
				times[i] = time;
				k++;
				i++;
			}
			if (DISP_ERROR_ALL) {
				System.out.println("Square Differences for each k, sequentially:");
				for (int j = 0; j

Hash Tables and Words

Taught by and aided by Dr. Holland-Minkley

Making a Hash Table to Predict Where Spaces Go In A Sentence Like iwishiwaslearningnow (Click Here to Download)

Code Preview
import java.util.Scanner;
import java.io.*;

public class WordsRank {
	//public static int dictionarySize = 354985;* 2 is 709970, nearest prime: 709967
	public static String[] dic = new String[709967];// collection of dictionary words
	public static int best = -1;		// number of dictionary words in best segmentation found
	public static String bestSeg = null;	// best segmentation found
	public static int bestLikely = -1;
	public static int bestWeight = -1;
	public static boolean assigned = false;

	// support method that stores all words in dictionary.txt in dic

	private static void storeDic() {
		try {
			int wc = 0;
			Scanner filescan = new Scanner(new File("words.txt"));
			while (filescan.hasNext()) {
				//dic[wc] = filescan.nextLine();
				String word = filescan.nextLine();
				insert(word);
				wc++;
			}
			System.out.println(wc + " words stored");
		} catch (IOException e) {System.out.println(e);}
	}
	
	public static int hash(String key) {
		long value = 0;
		char letter;
		int power = key.length();
		for (int i = 0; i < key.length(); i++) {
			letter = key.charAt(i);
			value += ((int) letter)
					* Math.pow(27, --power); //decrement power then use it
		}
		return (int)(value % dic.length);
	}
	
	public static int doubleHash(String key) { //handle collision
		//Another near prime: 709963
		long value = 0;
		char letter;
		int power = key.length();
		int nearPrime = 7;//709963;
		for (int i = 0; i < key.length(); i++) {
			letter = key.charAt(i);
			value += ((int) letter - 96)  //Can subtract
					* Math.pow(27, --power); //decrement power then use it
		}
		return nearPrime - (int)(value % nearPrime);
		//return 1; //For testing purposes
		
	}
	
	public static void insert(String key) { //Assume array is not full...
		int hashVal = hash(key);
		int stepSize = doubleHash(key);
		
		while (dic[hashVal] != null) {
			hashVal += stepSize; //move... update this
			hashVal %= dic.length; //wrap around
		}
		
		dic[hashVal] = key;
	}
	
	public static boolean find(String key) {
	      int hashVal = hash(key);  // hash the key
		  int stepSize = doubleHash(key);

	      while(dic[hashVal] != null)  // until empty cell,
	         {                               // found the key?
	         if(dic[hashVal].equalsIgnoreCase(key))
	            return true;   // yes, return item
	         hashVal += stepSize;      // go to next cell
	         hashVal %= dic.length;    // wraparound if necessary
	         }
	      return false;                  // can't find item
	}
	
	/*private static void storeDic() {
		try {
			int wc = 0;
			Scanner filescan = new Scanner(new File("words.txt"));
			while (filescan.hasNext()) {
				dic[wc] = filescan.nextLine();
				wc++;
			}
			System.out.println(wc + " words stored");
		} catch (IOException e) {System.out.println(e);}
	}*/
	
	public static void split(String head, String in) {	
		// head + " " + in is a segmentation 
		String segment = head + " " + in;
		//System.out.println(segment);

		// count number of dictionary words within the segmentation
		// update best and bestSeg if new best segmentation has been found
		String[] tokens = segment.split(" ");
		int count = -1;
		int weight = 0;
		int length = 0;
		final int SUBTRACT_FOR_ONE = 5; //How many points we want to sub
										//if only one letter. Must put back
										//for important words like "a"
		for (int i=0; i 5) { //Larger than 5? That's impressive, better boost it
					weight += length+2;
				}
				//oddities:
				if (word.startsWith("a")) {
					if (word.contains("dd") ||
							word.contains("tt"))
						weight += 4; // Double letters, increase weight if begins with a
				}
				//Add weight to certain words
				//Most important/used words:
				if (isArticle(word)) {
					weight += 4;
					if (length == 1)
						weight += SUBTRACT_FOR_ONE; //add back subtraction
					if (i > 0) {
						if (tokens[i-1].toLowerCase().equalsIgnoreCase(("i")))
								weight -= 10;
					}
				} else //Second most used words
				
				if (isImportant(word)) {
					weight += 2;
					if (length == 1)
						weight += SUBTRACT_FOR_ONE; //add back subtraction
					if (i > 0) {
						if ((!tokens[i-1].equalsIgnoreCase("am") 
								|| !tokens[i-1].equalsIgnoreCase("do"))
								&& isImportant(tokens[i-1])) { //If we have two in a row, bad
							weight -= 10; //
						}
					}
				}
				
				//Prioritize sentences with ending in ing/er
				if ((word.endsWith("ing") || word.endsWith("er"))
						&& length > 3) {
					weight += 2;
					if (word.contains("do"))
						weight += 9;
					
				}
				
				//Prioritize sentences with most words that end with s
				 if (endsWithS(word) && length > 1) {
						weight += 3; //Greater than the weight for length = 4
						if (i < tokens.length - 1) {
							if ((tokens[i+1].toLowerCase().startsWith("s") ||
									tokens[i+1].toLowerCase().startsWith(" s"))
									&& find(tokens[i+1]))
								weight += 3;
						}
				 }
				 if (word.startsWith("s") &&
						 word.endsWith(("s")) &&
						 word.length() > 2) {
					 weight += 7; //Needs to surpass weight of ending with s
				 } else
				 if (word.startsWith("s")) {
					 weight += 2; //undo end with s
				 }

				//Words that usually go together/don't:
				if (i < tokens.length-1) {
					String next = tokens[i+1].toLowerCase();
					if (word.equals("i")) {
						if (next.equals("am"))
							weight += 20;
						if (next.equals("was"))
							weight += 20;
					}
					if (word.equals("we") || 
							word.equals("they")) {
						if (next.equals("are"))
							weight += 20;
						if (next.equals("were"))
							weight += 20;
					}
					if (word.equals("me")) {
						if (isArticle(next))
							weight -= 20;
					}
					if (word.equals(("an"))) {//next must start with vowel
						if(!beginsWithVowel(next))
							weight -= 10;
					}
				}
				
				//Words to end with
				if (i == tokens.length - 1) {
				if (word.equals("them") || 
						word.equals("him") ||
						word.equals("her"))
					weight += 5;
				if (isArticle(word)) {
					weight -= 15;//shouldn't end with these...
				}
				}
			} else {
				weight -= 20; //Not a word. Big punishment.
				if (tokens[i].length() > 3) {
					weight -= 100;
				}
			}
			
		}
		if (!assigned) {
			best = count;
			bestSeg = segment;
			bestWeight = weight;
			assigned = true;
			System.out.println("Assigned.");
		} else
		if (weight > bestWeight || (weight == bestWeight && count < best)) {
				best = count;
				bestSeg = segment;
				bestWeight = weight;
				//System.out.println("FOUND NEW BEST: "+weight);
		}

		// recursive calls
		for (int i=1; i

Decision Trees

Code heavily aided and provided by Dr. Holland-Minkley. Changes were made per homework assigment. I am including this code to show what I have worked with. Most credit goes to Dr. AMH.

Making a Hash Table to Predict Where Spaces Go In A Sentence Like iwishiwaslearningnow (Click Here to Download)

Code Preview
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

// object class representing a single data item
class Mushroom {
	public String classification;	// "poisonous" or "edible"
	public String[] values;	// attribute vector
	
	public Mushroom(String c, String[] v) {
		classification = c;
		values = v;
	}
}

// node within the DecisionTree
class Node {
	public Node[] children;	// depending on the attribute, a variable number of children
	// note that children will be assumed to be attached in the same order as the values
	// are listed in the "values" array of the DecisionTree class
	public int index;	// index of the attribute associated with this node if it is internal
	public String classification;	// classification to return if this node is a leaf
	
	public Node() {
		children = null;
		index = -1;
		classification = null;
	}
	
	public Node(int num, int i) {
		children = new Node[num];
		index = i;
		classification = null;
	}
	
	public Node(String clss){
		children = null;
		index = -1;
		classification = clss;
	}
}

// class implementing a decision tree
class DecisionTree {
	public Node root;	// link to the root node of the tree
	public int numAttributes;	// number of attributes tree can be built over
	public String[][] values;	// set of possible values for all attributes

	public DecisionTree(String[][] v) {
		values = v;
		numAttributes = values.length;
		root = null;
	}

	

	//Predicts whether a mushroom is edible or not
	public String predict(Mushroom m, String[] labels, boolean verbose) {
		if (verbose) {
			System.out.println("Reasoning: ");
			return predictVerbose(root, m, labels); //need labels for category
		} else {
			return predictNoVerbose(root, m);
		}
	}
	
	
	//NOTE: The other predict method is more thoroughly commented, but applies here too
	private String predictVerbose(Node curr, Mushroom m, String[] labels) {
		if (curr.index == -1) { //base case, return prediction
			System.out.println("\tMushroom is predicted to be "+curr.classification.toUpperCase());
			return curr.classification;
		}
		//System.out.println(m.values[curr.index]);
		String mAttr = m.values[curr.index];
		String category = labels[curr.index]; //Need this to print out the category
		for (int i = 0; i = edible) return "poisonous";
	   else return "edible";
   }

   // given an attribute, a particular value for that attribute, and either
   // "poisonous" or "edible", return the number of items in this list that
   // have both the given value and the designated classification
   public int getClassCount(int attribute, String value, String clss){
	   int count = 0;
	   Link curr = first;
	   while (curr != null) {
		   if (curr.data.values[attribute].equalsIgnoreCase(value) &&
				   curr.data.classification.equalsIgnoreCase(clss)) count++;
		   curr = curr.next;
	   }
	   return count;	   
   }

   // given an attribute and a particular value for that attribute, return the
   // number of items in this list that have the given value for that
   // attribute
   public int getValueCount(int attribute, String value) {
	   int count = 0;
	   Link curr = first;
	   while (curr != null) {
		   if (curr.data.values[attribute].equalsIgnoreCase(value)) count++;
		   curr = curr.next;
	   }
	   return count;
   }
   
   // given an attribute and a particular value for that attribute, return the
   // sublist of this list which has only the Mushroom objects in it with
   // the given value for the attribute
   public MushList getSublist(int attribute, String value){
	   MushList newList = new MushList();
	   Link curr = first;
	   while (curr != null) {
		   if (curr.data.values[attribute].equalsIgnoreCase(value)) {
			   newList.insert(curr.data);
		   }
		   curr = curr.next;
	   }
	   return newList;
   }
   
   public int predict(DecisionTree t, String[] labels, boolean disp) {
	   Link curr = first;
	   int right = 0;
	   int times = 0;
	   while (curr != null) {
		   Mushroom m = curr.data;
		   String outcome = t.predict(m, labels, false);
		   if (outcome.equalsIgnoreCase(m.classification)) {
			   right ++;
		   }
		   times ++;
		   if (disp)
			   System.out.println(times+": Predicted:"+outcome+", really was: "+m.classification);
		   curr = curr.next;
	   }
	   return right;
   }
}

public class MushroomDT {
	public static void main (String[] args) throws IOException {
    	Mushroom mush = null; //hard-coded mushroom to predict
		int numAttributes = 22;	// number of attributes
		String[] labels; 	// label associated with each attribute
		String[][] values = {{"bell","conical","convex","flat","knobbed","sunken"},
				{"fibrous","grooves","scaly","smooth"},
				{"brown","buff","cinnamon","gray","green","pink","purple","red","white","yellow"},
				{"bruises","no"},
				{"almond","anise","creosote","fishy","foul","musty","none","pungent","spicy"},
				{"attached","descending","free","notched"},
				{"close","crowded","distant"},
				{"broad","narrow"},
				{"black","brown","buff","chocolate","gray","green","orange","pink","purple","red","white","yellow"},
				{"enlarging","tapering"},
				{"bulbous","club","cup","equal","rhizomorphs","rooted","?"},
				{"fibrous","scaly","silky","smooth"},
				{"fibrous","scaly","silky","smooth"},
				{"brown","buff","cinnamon","gray","orange","pink","red","white","yellow"},
				{"brown","buff","cinnamon","gray","orange","pink","red","white","yellow"},
				{"partial","universal"},
				{"brown","orange","white","yellow"},
				{"none","one","two"},
				{"cobwebby","evanescent","flaring","large","none","pendant","sheathing","zone"},
				{"black","brown","buff","chocolate","green","orange","purple","white","yellow"},
				{"abundant","clustered","numerous","scattered","several","solitary"},
				{"grasses","leaves","meadows","paths","urban","waste","woods"}};

		Scanner fileScan = new Scanner(new File("mushrooms.csv"));
		String header = fileScan.nextLine();
		// read in the label associated with each attribute from the first line
		// of the csv file
		Scanner labelScan = new Scanner(header);
		labelScan.useDelimiter(",");
		labelScan.next();
		labels = new String[numAttributes];
		for (int i=0; i
PHOTOGRAPHY

My digital media.

CIS 271: Taught by Dr. Samuel Fee

Image: Look to the Green

Original (later editted in Photoshop):
Original Look to the Green

Look to the Green

Final Version:
Editted Look to the Green This photograph of a mountain range in West Virginia was designed to be aesthetically pleasing and translate a positive message. The mountain ranges are colored in such a way that creates a huge contrast between the first mountain range and second and third mountain ranges. The first mountain range was made brown, dead, and some-what "ugly," but in an aesthetically pleasing way as it contrasts with the colors of the subsequent mountain ranges and sky. I exposed the second mountain range's beauty and made it aesthetically pleasing by emphasizing its cool colors such as green. Then the third and most distant mountain range's colors were emphasized the most to give a different, yet still green, look. Trying to give the photograph some depth, I added an apparent distance between the mountain ranges through the camera raw filter's dehaze settings.
Originally, I wanted to only create a more beautiful photograph; however, I felt a need to encode a message in it. In this photograph, I encoded a message that is similar to "Look to the Future." I tried output a positive connotation and encode a positive message. If you were to look at this picture from down to up, or from the mountain range closest to you (like from where you would be standing) to the mountain range farthest away (what your future journey may hold), you would see that the first mountain range is brown, the second is green, and the third is a little bit greener. In this image, the appropriated theme of "Look to the Future" is actually "Look to the Green." Because green usually symbolizes wealth, rebirth, or growth and brown is dead and depressing, this photograph is a representation of the journey of life. Just because you are in a bad, depressing, or dead spot in your life does not mean that your future is not very much alive.

Image: Ghost Town

Original (later editted in Photoshop):
Original Ghost Town

Ghost Town

Final Version:
Editted Ghost Town
This photograph was taken and then edited to be more colorful and enticing as well as to keep a realistic look. I wanted to capture a clean and sleek photograph of Washington, Pa, while also giving it an old-town feel and connotation. While designing the photograph, I wanted to make the center building the focal point. This was achieved by cropping the image to the rule of thirds and through the removal of the telephone lines. Additionally, the building was selected using the quick selection tool and its sharpness was increased which really brightened it up and made it more noticeable. I picked this building as the focal point because I believe it is the most interesting building in the photograph. I thought the building looked old and creepy and increasing the sharpness on that building, not only made it stand out more, but increased the creepy and lifeless connotation of the photograph. I added a lot of contrast throughout the entire photograph. Most notably, the sky and the clouds have a lot of contrast and beautiful coloring that was brought out through the camera raw filter. I love beautiful skies, so that is what I am aimed to do in this photograph. The trees along the side-walk are dead, which adds to that eerie connotation of the photograph. The orange tree to the right of the photo reminds us that the season is Fall, a season of life ending, and yet contrasts with the bright blue sky and the green grass (the grass was made green on purpose to add to the aesthetics and overall contrast). Everything in the photograph is pretty much dead (the trees, the bushes, the grass across the street) which contrasts with the alive green grass and bright blue sky. Note that the green grass is on the opposite side of the lifeless town. To make the photograph seem more lifeless and less modern, the cars driving past were removed. This adds to its 'Ghost Town' feeling and makes the picture feel like it was taken in the late 1900s rather than in 2019. Furthermore, the sky is beautiful, yet it looks like the world is in chaos. This photograph has had its photographic truth blurred the most out of all the images in my portfolio.

Image: Taking the Stairway to Heaven

Create in Photoshop

Taking the Stairway to Heaven

Taking the Stairway to Heaven I decided to appropriate Led Zeppelins album cover with me playing a bass guitar because Led Zeppelin is a band that has influenced me and because the album cover is beautiful. I made myself a cartoon to fit in and be consistent (repetition) with the coloring and drawing of the album cover's photo. I ensured that the scaling of my cartoon was appropriate to fit in on the staircase. I wanted it to appear as if I was playing bass on the Stairway to Heaven. Additionally, I liked the idea of making myself a drawing, similar to the album cover, because our path in life is malleable and can be changed/formed by our actions. This is similar to drawing a picture where the life of what we draw can take many forms and be anything we put our minds to.

PYTHON AND NUMERICAL COMPUTATION

My code and projects.

CIS 341: Taught by Dr. Gregory Hallenbeck

Final Project

Networks

Researching and coding Networks in Python (Click to Download Code)

Download the code by clicking here

PowerPoint Presentation:
Python Notebook Depiction of Networks:
Where to find me

Pittsburgh, PA

Email Me At

JamesMastran@gmail.com
MastranJ@jay.washjeff.edu
Jam2454@columbia.edu

Call Me At

Mobile: (+1) 412 877 0484