Skip to content

The Bryan Home Shopping Saga

…or “Why I decided not to buy a condo right now after all.”

Since I keep having to tell people the story, then I figured I might as well write it down. It might also be a good reference for me.

OK. So here’s what happened.

Late in 2009, I started getting serious about home shopping. For all the obvious reasons (independence, taxes, space, etc, etc.) it felt like the right time. Throw in the fact that I just landed a great job, interest rates were 5%, the government was giving away $8,000 in tax credit, and Washington State was going to loan me $10,000 for a downpayment– and everything seemed absolutely perfect! Or at least, that’s what everybody in the real estate business would have you believe…

During that time my boss had made a few offhanded comments about how it was an absolutely terrible time to buy a house. I didn’t dismiss him outright, I just believed that the condo I was looking at was a special situation– after all it had come down $100,000!

The particular condo I was looking at had been on the market for about a year. In that year, it had come down in price from $360,000 (or so) to $258,500. AND it is right next to my brother’s place– Bonus!

In January I decided to get serious about shopping, and make sure that I checked out the competition. I visited about 10 other condos, and was not impressed with any of them. The value/dollar ratio was seeming better and better to me. I started making preparations to buy, and I got pre-approved for financing (absurd gobs of money!) in early February.

After pre-approval, I finally made an offer of $245,000 on the place. I was scared out of my mind! I signed about 50 times in 15 pages that I was serious about buying this place– and I was. It happened that I made my offer on a Wednesday, and I heard nothing for two days, until Friday afternoon. They rejected my offer of $245,000 and made a counteroffer of $255,000. I decided, now that it was almost too late, I should really talk to my boss and get the lowdown on why now is a terrible time to buy.

He proceeded to blow my mind.

I stopped by his office Friday evening after work, and he was nice enough to give me a lecture for about an hour and a half. He showed me charts, graphs, articles, ratios, etc, etc that proved I would have to be monumentally stupid to buy right now.

This is the one that stuck with me:

irrational exuberance, indeed

SO. After all of that happened. I had a $255K counteroffer on the table, which I let expire, much to the seller’s disappointment.

After a week or two of contemplating whether or not to make another offer, I decided I would, and I sent the following message to my real estate agent. (This is pretty much the stuff that my boss showed me.)

After considering my options, I will go ahead and make an offer of $202,000.

I believe this offer is in everybody’s best interest:

  • At an appreciation rate 4%, $202,000 represents a fair value for their property, and a healthy margin too.

    • $250,000 represents a 6.86% appreciation rate.
      • If this rate were sustained, then our children would never be able to buy homes because prices would outstrip inflation.
    • $350,000 represents an 11.45% appreciation rate.
  • I believe this is the best price they can get, now, or within two years.
  • Their time is valuable. I know it is obvious, but the sooner they can sell, the sooner they can move to where they want to be.
  • Money is valuable. Again, it’s obvious, but the sooner they can sell, the sooner they have more cash flow available.
  • Every indicator available points to a continued decline in real estate prices
    • Foreclosures are expected to increase after January, adding even more low-priced supply to the market.
    • After March 31st, the government will discontinue buying mortgage-backed securities.
      • Without that subsidy, interest rates are widely expected to rise, reducing buying power.
    • The first time home buyer tax credit will expire in April, lowering demand from FHA buyers (40% of the market).
    • The Seattle market is still reaching new lows, according to the Case-Shiller
      index
      . December (the latest available month) marked a new 4-year low in
      home values for the area.
    • Existing home sales dropped in January.
    • New home sales have hit a new record low in January.
    • The bubble has not been fully corrected yet.

All of this indicates to me that buying a house now will most likely mean some depreciation, even at $202,000.

So why would I still be looking to buy at this price?

  • One year’s worth of rent payments, at $1,300/month for a comparable
    apartment, is worth $15,600. The delta between that and my projected mortgage payment would be relatively small.
  • Assuming that depreciation did not continue too far into 2011, the direct tax and cash flow benefits for me owning my own home would outweigh the downside.
  • The price of a mortgage is really low right now. 5% is a rate I‘ll not soon see again.
  • $8,000 tax credit is an added bonus.
  • Most importantly, after only 3-4 years I would have a good chance of being able to sell this home for at least the same amount of money. At a purchase price of $250K, I do not believe that is the case.

I realize, after my initial offer, that this one will be more difficult to evaluate independently. However, this offer more accurately reflects the current demand of the market, and I sincerely believe there will not be a better offer available anytime soon.

I would like to present Martin & Susie with this information. I think it is important that both sides have the full context of what this deal means for the other party. I have mentioned my reasons for wanting to buy in spite of the market. I would like to know their reason for selling– if for nothing else besides context.

I did not expect a response to my “insulting” offer, but the sellers surprised me. They actually let my agent know that they probably would have sold at that price, but were now underwater on their mortgage. It’s a sad situation.

Luckily, I have avoided that fate.

Update: For fun, I will track the price of the nearest condo on Zillow. I want to see where it is at in about 18 months, versus where it is at today.

12517 NE 23rd Pl # A-1, Bellevue, WA
Zestimate $236,500

Making a Fractal in Java’s Console

From, Data Structures and Other Objects Using Java, Chapter 8, Project #9, page 440:

Examine this pattern of asterisks and blanks and write a recursive method that can generate exactly this pattern:

*
* *
  *
* * * *
    *
    * *
      *
* * * * * * * *
        *
        * *
          *
        * * * *
            *
            * *
              *

With recursive thinking, the method needs only seven or eight lines of ode (including two recursive calls). How is this pattern a fractal? Your method should also be capable of producing larger or smaller patterns of the same variety. Hint: Have two parameters. One parameter indicates the indentation of the leftmost line in the pattern; the other parameter indicates the number of stars in the longest line.

WARNING: Cheating is bad, mmmmkay children? Don’t cheat.


 /*
|	Bryan Simonson
 \	CS211 - Craig Niiyama
  | 2/21/2010
*/

package bryansimonson;

public class Fractal {
	public static void main(String args[]){
		drawFractal(32,0);
	}

	public static void drawFractal(int length, int space){
		if (length==1){ // the stopping case
			for (int n=0; n<space; n++) System.out.print("  ");
			System.out.println("* ");
		} else {		// length is a power of two
			drawFractal(length/2,space);
			for (int n=0; n<space; n++) System.out.print("  ");
			for (int n=0; n<length; n++) System.out.print("* ");
			System.out.println();
			drawFractal(length/2,length/2+space);
		}
	}
}

Simulating a Car Wash in Java

From, Data Structures and Other Objects Using Java, Chapter 7, Project #8, page 396:

Make improvements to the car was simulation program

from Section 7.2.

Note: Portions of code taken from Michael Main’s version.

WARNING: Cheating is bad, mmmmkay children? Don’t cheat.


 /*
|	Bryan Simonson
 \	CS211 - Craig Niiyama
  | 2/21/2010
*/

// FILE: Carwash.java
// This program illustrates the use of the carWashSimulate method which uses
// a simple queue to simulate cars waiting at a car wash.
package bryansimonson;
import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import edu.colorado.simulations.BooleanSource;
import edu.colorado.simulations.Washer;
import edu.colorado.simulations.Averager;

/******************************************************************************
* The <CODE>CarWash</CODE> Java application illustrates the use of
* the <CODE>carWashSimulate</CODE> method.
* The illustration uses the following values:
*   <CODE>
*   <br>washTime = 240
*   <br>arrivalTime = 0.0025
*   <br>totalTime = 6000
*   </CODE>
*
* <p><dt><b>Java Source Code for this class:</b><dd>
*   <A HREF="../applications/CarWash.java">
*   http://www.cs.colorado.edu/~main/applications/CarWash.java
*   </A>
*
* @author Michael Main
*   <A HREF="mailto:main@colorado.edu"> (main@colorado.edu) </A>
*
* @version
*   Jun 12, 1998
******************************************************************************/
public class CarWash
{
   /**
   * The main method activates <CODE>carWashSimulate</CODE> with the values:
   *   <CODE>
   *   <br>washTime = 240
   *   <br>arrivalTime = 0.0025
   *   <br>totalTime = 6000
   *   </CODE>
   * <BR>The <CODE>String</CODE> argument (<CODE>args</CODE>) is not used in
   * this implementation.
   **/
   public static void main(String[ ] args) throws IOException
   {
	  BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in));

	  // get total length of simulation from the user
      System.out.println("How many seconds would you like to simulate?");
      System.out.println("(Default is 6000)");
      int simtime = Integer.parseInt(stdin.readLine());

      // get the probability of a new customer from the user
      System.out.println("What is the probably of a new customer arriving in any given second?");
      System.out.println("(Default is 0.0025)");
      double probability = Double.parseDouble(stdin.readLine());

      // get the number of seconds it takes to wash the car from the user
      System.out.println("How many seconds does it take to wash one car?");
      System.out.println("(Default is 240)");
      int washtime = Integer.parseInt(stdin.readLine());

      carWashSimulate(washtime, probability, simtime);
   }

   /**
   * Simulate the running of a car washer for a specified amount of time.
   * @param <CODE>washTime</CODE>
   *   the number of seconds required to wash one car
   * @param <CODE>arrivalProb</CODE>
   *   the probability of a customer arriving in any second, for example
   *   0.1 is 10%
   * @param <CODE>totalTime</CODE>
   *   the total number of seconds for the simulation
   * <dt><b>Precondition:</b><dd>
   *   <CODE>washTime</CODE> and <CODE>totalTime</CODE> are positive;
   *   <CODE>arrivalProb</CODE> lies in the range 0 to 1.
   * <dt><b>Postcondition:</b><dd>
   *   The method has simulated a car wash where <CODE>washTime</CODE> is the
   *   number of seconds needed to wash one car, <CODE>arrivalProb</CODE> is
   *   the probability of a customer arriving in any second, and
   *   <CODE>totalTime</CODE> is the total number of seconds for the
   *   simulation. Before the simulation, the method has written its three
   *   parameters to <CODE>System.out</CODE>. After the simulation, the method
   *   has written two pieces of information to <CODE>System.out</CODE>:
   *   (1) The number of cars washed, and (2) The average waiting time for
   *   customers that had their cars washed. (Customers that are still in the
   *   queue ARE included in this average).
   * @exception java.lang.IllegalArgumentException
   *   Indicates that one of the arguments violates the precondition.
   **/
   public static void carWashSimulate
   (int washTime, double arrivalProb, int totalTime)
   {
      Queue<Integer> arrivalTimes = new LinkedList<Integer>( );
      int next;
      BooleanSource arrival = new BooleanSource(arrivalProb);
      Washer machine = new Washer(washTime);
      Averager waitTimes = new Averager( );
      int currentSecond;

      // Write the parameters to System.out.
      System.out.println("Seconds to wash one car: " + washTime);
      System.out.print("Probability of customer arrival during a second: ");
      System.out.println(arrivalProb);
      System.out.println("Total simulation seconds (open \"hours\"): " + totalTime);

      // Check the precondition:
      if (washTime <= 0 || arrivalProb < 0 || arrivalProb > 1 || totalTime < 0)
         throw new IllegalArgumentException("Values out of range"); 

      for (currentSecond = 0; currentSecond < totalTime || !arrivalTimes.isEmpty(); currentSecond++)
      {  // Simulate the passage of one second of time.

         // Check whether a new customer has arrived.
         if (arrival.query( ) && currentSecond <= totalTime)
            arrivalTimes.add(currentSecond);

         // Check whether we can start washing another car.
         if ((!machine.isBusy( ))  &&  (!arrivalTimes.isEmpty( )))
         {
            next = arrivalTimes.remove( );
            waitTimes.addNumber(currentSecond - next);
            machine.startWashing( );
         }

         // Subtract one second from the remaining time in the current wash cycle.
         machine.reduceRemainingTime( );
      }

      // Write the summary information about the simulation.
      System.out.println("Customers served: " + waitTimes.howManyNumbers( ));
      if (waitTimes.howManyNumbers( ) > 0)
         System.out.println("Average wait: " + waitTimes.average( ) + " sec");

      // Print ending second to compare to expected "closing time"
      System.out.println("Ending second (or last customer served): " + currentSecond);
   }

}

Solving the nQueens Problem in Java

From Data Structures and Other Objects Using Java, Chapter 6, Project #10, Page #347:

Suppose that you have n queens from a chess game, and that you also have an n-by-n chess board. Is it possible to place all n queens on the board so that no two queens are in the same row, no two queens are in the same column, and no two queens are on the same diagonal?

WARNING: Cheating is bad, mmmmkay children? Don’t cheat.

n Queens source code:


 /*
|	Bryan Simonson
 \	CS211 - Craig Niiyama
  | 2/21/2010
*/

package bryansimonson;
import edu.colorado.collections.*;

public class nQueens {
	public static void main(String[] args) {
		final int QUEENS = 40;
		queens(QUEENS);
	}

	public static void queens(int n){
		boolean success = false;

		// row = the row within the stack, column = the row's integer value
		ArrayStack<Integer> s = new ArrayStack<Integer>(n);
		s.push(1);

		while (!success && !s.isEmpty()){
			int x=0;	// placeholder for when we pop values
			boolean conflict = false;

			// check for conflicts
			for (int i=1; i<s.size(); i++){
				int deltarows = s.size()-i;
				if (	// no need to check row, stack preempts row conflict
						s.peek()==s.itemAt(i) ||			// same column
						s.peek()==s.itemAt(i)+deltarows ||	// same diagonal
						s.peek()==s.itemAt(i)-deltarows		// same diagonal
					) conflict = true;
			}

			if (conflict){
				while (s.peek()==n)
					x=s.pop();
				if (!s.isEmpty())
					s.push(s.pop()+1);
				else
					s.push(x+1);
			} else if (!conflict && s.size()==n){
				success = true;
			} else {
				// new row, so try column 1
				s.push(1);
			}
		}

		// print out the board with the queens
		for (int x=1; x<=s.size(); x++){
			for (int y=1; y<=n; y++){
				if (s.itemAt(x)==y)
					System.out.print("X ");
				else
					System.out.print("O ");
			}
			System.out.println();
		}

	}
}

PseudoRandom Number Generation in Java

Assignment number 1 in CS211 (Java) programming class. (No stealing! I want full point on my grade!)

PseudoRandomDemo.java


 /*
|	Bryan Simonson
 \	CS211 - Craig Niiyama
  | 1/19/2010
*/

package bryansimonson;
import bryansimonson.PseudoRandom;

/**
 * @author Bryan Simonson (manticor@gmail.com)
 */
public class PseudoRandomDemo {

	/**
	 * The main function generates a table that counts how many
	 * instances of a pseudorandom number fall within a certain range.
	 */
	public static void main(String[] args) {
		final int INTRVL = 10;				// interval of distribution table
		final int LOOPS = 1000000;			// number of times to run loop
		final int SEED = 1;					// initial seed value
		final int INCR = 3641;				// increment
		final int MOD = 729;				// modulus
		final int MULT = 40;				// multiplier
		int[] dist = new int[INTRVL];		// distribution table

		PseudoRandom x = new PseudoRandom(SEED, MULT, INCR, MOD);

		System.out.println("Output of PseudoRandomDemo");
		System.out.println();

		// Show initial values
		System.out.println("Initial values");
		System.out.println("Interval:\t"+INTRVL);
		System.out.println("Seed:\t\t"+SEED);
		System.out.println("Multiplier:\t"+MULT);
		System.out.println("Increment:\t"+INCR);
		System.out.println("Modulus:\t"+MOD);
		System.out.println();

		// Demonstrate current() function
		System.out.println("Demonstrate current() function");
		System.out.println(x.current());
		System.out.println();

		// Demonstrate next() function
		System.out.println("Demonstrate next() function");
		System.out.println(x.next());
		System.out.println(x.next());
		System.out.println(x.next());
		System.out.println();

		// Demonstrate nextMod() function
		System.out.println("Demonstrate nextMod() function");
		System.out.print("nextMod() value: ");
		System.out.printf("%6.2f",x.nextMod());
		System.out.println();
		System.out.println("new seed value:"+x.current());

		// Demonstrate changeSeed() function
		x.changeSeed(SEED);
		System.out.println("\nSeed has been reset using changeSeed("+SEED+")\n");

		// Populate array with count of instances between each interval
		for (int i = 0; i<LOOPS; i++){
			dist[(int)(x.nextMod()*INTRVL)]++;
		}

		// Print out a table with instance counts per interval
		System.out.println("Count of instances");
		System.out.println("Range\t\tNumber of Occurrences");
		for (int i=0; i<INTRVL; i++){
			System.out.println(
					"["+
					((double)(i)/INTRVL)+
					".."+
					((double)(i+1)/INTRVL)+
					")\t"+
					dist[i]
			);
		}
	}
}

PseudoRandom.java (Class)


package bryansimonson;

 /*
|	Bryan Simonson
 \	CS211 - Craig Niiyama
  | 1/19/2010
*/

/**
 * @author Bryan Simonson (manticor@gmail.com)
 *
 */
public class PseudoRandom {
	private int seed;
	private int multiplier;
	private int increment;
	private int modulus;

	/**
	 * Constructor for PseudoRandom object.
	 * @param firstseed - The original seed value
	 * @param mult - Multiplier
	 * @param incr - Increment
	 * @param mod - Modulus value
	 */
	public PseudoRandom (int firstseed, int mult, int incr, int mod){
		multiplier = mult;
		increment = incr;
		modulus = mod;
		seed = (mult * firstseed + incr) % mod;
	}

	/**
	 * Access the current seed value
	 * @return
	 * 	The current seed value
	 */
	public int current(){
		return seed;
	}

	/**
	 * Generates the next pseudorandom number iteration
	 * @return
	 * 	The next pseudorandom number iteration
	 * @postcondition
	 * 	The current seed value set to the same value that is returned
	 */
	public int next(){
		seed = (multiplier * seed + increment) % modulus;
		return seed;
	}

	/**
	 * Change the current seed value
	 * @param newseed
	 * @postcondition
	 * 	The current seed value is replaced by <code>newseed</code>
	 */
	public void changeSeed(int newseed){
		seed = newseed;
	}

	/**
	 * Generates the next pseudorandom number divided by the modulus value
	 * @return
	 * 	a double in the range [0..1)
	 * @postcondition
	 * 	the current seed value is set to whatever the next pseudorandom integer
	 */
	public double nextMod(){
		return (next()/(double)modulus);
	}
}

Geek Pride

I just read this article from the New York Times about getting rid of the words “geek” and “nerd” because they’re pejorative.

What a nerd. A geek would know the difference.

There’s a reason why the saying goes “The GEEKS shall inherit the Earth,” and that is because we geeks are cool enough to make it into somebody’s will.

C++ Date Class – Manipulate Dates in C++

Finally! I did it! Assignment #4 is complete, and I can manipulate dates pretty effing easily now.

No doubt there is already some vastly superior date manipulation library already out there… stupid school.

:) Just kidding. I learned a LOT with this assignment.


#include <iostream>
using namespace std;

class Date {

private:
	 /*
	|
	 \	PRIVATE DATA
	  |
	*/
	static const int EpochYear = 1752;
	static const int EpochMonth = 9;
	static const int EpochDay = 14;
	static const int EpochDoW = 5;		// must define day of week of epoch (5 = Thursday)
	int epochdays;						// this is the number of days since September 14, 1752
	int month,day,year;					// the current value of month/day/year
	bool validdate;

	 /*
	|
	 \	PRIVATE MEMBER FUNCTIONS
	  |
	*/
	bool isLeapYear(int year){
		// check if this year is a leap year, return false if not
		bool leapyear;

		if ((year % 4) == 0){
			if (year % 100 == 0){
				leapyear = false;
				if (year % 400 == 0){
					leapyear = true;
				}
			} else {
				leapyear = true;
			}
		} else {
			leapyear = false;
		}
		return leapyear;
	}

	int daysInMonth(int m, int y){
		// returns the number of days in a given month (1 =  January, etc)
		// invalid month/year combinations return -1
		int days = -1;
		int febdays = 28;

		if (isLeapYear(y))
			febdays = 29;

		switch (m){
			case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break;
			case 2: days = febdays; break;
			case 4: case 6: case 9: case 11: days = 30; break;
			default: days = -1; break;
		}
		return days;
	}

	int dayOfYear(int m, int d, int y){
		// return the day of year (eg, Jan 1 = 1, Dec 1 = 365 (or 366 on leap years))
		int daycount = 0;		// holds number of days elapsed this year

		// leap through every fully elapsed month
		for (int i=1; i<m; i++){
			daycount += daysInMonth(i,y);
		}

		// don't forget to add the elapsed days of this month
		daycount += d;

		return daycount;
	}

	int getEpochDays(int m, int d, int y){
		// for a given m/d/y, return the number of days since the epoch, 9/14/1752
		int daycount;	// this will be count of epochdays
		int thisDOY = dayOfYear(m,d,y);
		int epochDOY = dayOfYear(EpochMonth,EpochDay,EpochYear);

		// subtract day of year from epoch
		daycount = thisDOY - epochDOY;

		// add days for each fully elapsed year
		while (y > EpochYear){
			y--;	// decrement year now to avoid overcounting leap year
			if (isLeapYear(y)){
				daycount += 366;
			} else {
				daycount += 365;
			}
		}

		return daycount;
	}

	void convertEpochDays(int daysSinceEpoch, int& m, int& d, int& y){
		// SHOULD NOT be using m/d/y variables to calculate!
		int mm = EpochMonth;
		int dd = EpochDay;
		int yyyy = EpochYear;

		while (daysSinceEpoch > 0){
			//cout << "days left: "<< daysSinceEpoch << endl;
			if (daysSinceEpoch >= 366){
				// we have at least a year left
				yyyy++;	// increment year now to avoid taking credit for already elapsed leap day
				if (isLeapYear(yyyy)){
					daysSinceEpoch -= 366;
				} else {
					daysSinceEpoch -= 365;
				}
			} else if (daysSinceEpoch >= 31){
				// we have 31 or more days left
				if (mm == 12){
					daysSinceEpoch -= daysInMonth(mm,yyyy);
					mm = 1;
					yyyy++;
				} else {
					daysSinceEpoch -= daysInMonth(mm,yyyy);
					mm++;
				}
			} else {
				// we have up to 30 days left
				if (dd < daysInMonth(mm,yyyy)){
					dd++;
					daysSinceEpoch--;
				} else if (dd == daysInMonth(mm,yyyy)){
					mm++;
					dd = 1;
					daysSinceEpoch--;
				} else {
					cout << "You didn't account for something!"<< endl;
				}
			}
		}

		m = mm;
		d = dd;
		y = yyyy;
	}

public:
	// constructors
	Date(){
		// set default date to September 14, 1752
		month = 9;
		day = 14;
		year = 1752;
		epochdays = 0;
		validdate = true;
	}

	Date(int m, int d, int y){
		 /*
		|	Sets date with user input, verifies if proper date is provided
		 \	for any problem with user input: status member function will return false
		  | - do not allow date prior to September 14, 1752
		*/	

		// set defaults, assume the user is wrong about everything
		month = 9;
		day = 14;
		year = 1752;
		epochdays = 0;
		validdate = false;

		// month cannot be less than 1 or greater than 12
		if (m >= 1 && m <= 12){
			// month is valid. so far, so good
			// what about days? they can less than <1 or greater than that month's days
			if (d >= 1 && d <= daysInMonth(m,y)){
				// date format is valid, but is it at least 9/14/1752?
				if (getEpochDays(m,d,y) >= 0){
					month = m;
					day = d;
					year = y;
					epochdays = getEpochDays(m,d,y);
					validdate = true;
				}
			}
		}
	}

	// member functions
	bool status(void){
		// if date setting has any problems, returns false
		return validdate;
	}

	bool setdate(int m, int d, int y){
		 /*
		|	Sets date with user input, verifies if proper date is provided
		 \	for any problem with user input, returns false, no date change made
		  | - do not allow date prior to September 14, 1752
		*/	

		bool validnewdate = false;	// assume invalid new date (guilty until proven innocent)

		// month cannot be less than 1 or greater than 12
		if (m >= 1 && m <= 12){
			// month is valid. so far, so good
			// what about days? they can less than <1 or greater than that month's days
			if (d >= 1 && d <= daysInMonth(m,y)){
				// date format is valid, but is it at least 9/14/1752?
				if (getEpochDays(m,d,y) >= 0){
					month = m;
					day = d;
					year = y;
					epochdays = getEpochDays(m,d,y);
					validdate = true;
					validnewdate = true;
				}
			}
		}
		return validnewdate;
	}

	int getmonth(void) const {
		// returns month if status is true (Jan=1, Feb=2, etc)
		// if status is false, returns -1
		if (validdate)
			return month;
		else
			return -1;
	}

	int getday(void) const {
		// returns day if status is true; if status is false returns -1
		if (validdate)
			return day;
		else
			return -1;
	}

	int getyear(void) const {
		// returns year if status is true (eg: 2009,2010,1976)
		// if status is false returns -1
		if (validdate)
			return year;
		else
			return -1;
	}

	bool advance(int i){
		// adds i days to date, i may be positive or negative
		// returns false if there any problems
		if ((epochdays + i) >= 0){
			// increment epochdays to advance date
			epochdays += i;

			// now that we know the new count of epochdays, set m/d/y
			convertEpochDays(epochdays,month,day,year);

			return true;
		} else {
			cerr << "Could not set date prior to September 14, 1752." << endl;
			return false;
		}
	}

	int dleft(void){
		// returns days left in the year (eg, December 1st would return 30)
		int daysleft;

		if (validdate)
			daysleft = dayOfYear(12,31,year) - dayOfYear(month,day,year);
		else
			daysleft = -1;

		return daysleft;
	}

	int diff(Date d){
		 /*
		|	determine the number of day difference from argument
		 \	positive return value means date in argument is after class date, negative means before
		  | (eg; if object date is 2/3/09 and argument d is 2/6/09, function will return 3
		*/
		int m,dom,y,diffDays;
		m = d.getmonth();
		dom = d.getday();
		y = d.getyear();

		if (d.status())
			diffDays = epochdays - getEpochDays(m,dom,y);
		else
			diffDays = 0;	// return 0 for comparisons to invalid dates

		return diffDays;
	}

	int dofw(void){
		 /*
		|	returns day of week (Sunday=1,Monday=2, etc)
		 \	NOTE: September 14th, 1752 was a Thursday (dofw = 5)
		  | So if (epochdays % 7) == 0 then dofw = 5; 1 then dofw = 6; etc
		*/
		int dayofweek;
		if (validdate)
			dayofweek = ((epochdays % 7) + EpochDoW);
		else
			dayofweek = -1;

		return dayofweek;
	}

};

Vote Counting Machine: Borda & Plurality

This was my version of a C++ assignment to count votes from a text file. It’s not super useful outside the classroom, but I’m posting it anyway.


//
// Bryan Simonson
// Assignment #3
// Vote Counter
//

#include <fstream>
#include <string>
#include <iostream>
using namespace std;

// Function prototypes
int MenuSelect(void);
void LoadData(char vote[][100], int& candcount, int& votercount);
void PrefSched(char vote[][100], int& candcount, int& votercount);
void Plurality(char vote[][100], int& candcount, int& votercount);
void Borda(char vote[][100], int& candcount, int& votercount);
void PrintSpace(void);

int MenuSelect(){
	int menuoption = 0;

	cout << "\n\n\nMain Menu" << endl;
	cout << "==================================" << endl;
	cout << "1) Load Data" << endl;
	cout << "2) Preference Schedule" << endl;
	cout << "3) Plurality" << endl;
	cout << "4) Borda Count" << endl;
	cout << "5) Exit Program" << endl;
	cout << "==================================" << endl << endl;

	while (menuoption != 1 && menuoption != 2 && menuoption != 3 && menuoption != 4 && menuoption != 5){
		// Selection is invalid, prompt again
		cout << "Please enter a number between 1 and 5:" << endl;
		cin >> menuoption;
	}
	return menuoption;
}

void LoadData(char vote[][100], int& candcount, int& votercount){
	ifstream datafile;
	string filename, line;
	int cand = 0;
	int voter = 0;

	// Prompt for the filename. Unfortunately they'll have to type for now...
	cout << "Please type name of the file that contains vote data. (eg, \"votedata.txt\")" << endl;
	cin >> filename;

	// try to open file... if not, they're screwed (for now)
	datafile.open(filename.c_str());

	while (! datafile.eof()){
		getline(datafile,line);
		if (line.size() == 0){				// reached a blank line
			voter++;						// count a new voter
			cand = 0;						// reset "ballot" for new voter
		} else {
			vote[cand][voter] = line.at(0); // record vote
			cand++;
		}
	}

	// correct off by one issue from parsing empty lines
	voter = voter + 1;

	// set reference variables to the last count of voters/candidates
	candcount = cand;
	votercount = voter;

	// close the datafile
	datafile.close();

	cout << "Data loaded: "<< cand << " candidates, " << voter << " voters\n\n" << endl;
}

void PrefSched(char vote[][100], int& candcount, int& votercount){
	// Preference Schedule
	// Need to find all the different voting combos
	// and tell the user how many times they appeared

	// preference is a voter attribute
	// to get something comparable we need to create a string by concatenating each column
	string voterpref,comparestring;
	int score;

	for (int i=0;i<votercount;i++){
		voterpref = "";		//reset compare string
		for (int n=0;n<candcount;n++){
			voterpref.push_back(vote[n][i]);

			// time to compare
			score = 0;
			if (n == (candcount-1)){
				// end of column, we have the full string so let's compare

				for (int x=0;x<votercount;x++){
					// reset compare string
					comparestring = "";

					for (int y=0;y<candcount;y++){
						// generate same string for comparison purposes
						comparestring.push_back(vote[y][x]);

						if (y == (candcount-1)){
							if (voterpref == comparestring){
								score++;
							}
						}
					}
				}

				// finally, let's print the result
				cout << voterpref << " - " << score << endl;
			}
		}
	}
}

void Plurality(char vote[][100], int& candcount, int& votercount){
	int score;

	cout << "==========================" << endl;
	cout << "Plurality Count" << endl;
	cout << candcount << " candidates, " << votercount << " voters" << endl;
	cout << "==========================" << endl;

	// Need to count first place votes for each candidate
	for (int n = 0; n<candcount; n++){
		score = 0;
		for (int i = 0; i<votercount; i++){
			// compare first column to first row
			if (vote[n][0] == vote[0][i]){
				score++;
			}
		}
		cout << vote[n][0] << " - " << score << endl;
	}
}

void Borda(char vote[][100], int& candcount, int& votercount){
	// Borda scoring
	// Scoring depends on number of candidates
	int score = 0;

	cout << "==========================" << endl;
	cout << "Borda Count" << endl;
	cout << candcount << " candidates, " << votercount << " voters" << endl;
	cout << "==========================" << endl;

	// we want to print out each candidate's score only once, so loop through candidates
	for (int i = 0; i<candcount; i++){
		score = 0;
		cout << vote[i][0] << " - ";

		// for each candidate we have to go through the entire table for matches
		// this time as x gets higher, preference (multiple) gets lower
		for (int x = 0, multiple = candcount; x<candcount; x++, multiple--){
			for (int n = 0; n<votercount; n++){
				if (vote[i][0] == vote[x][n]){
					// match found, add points to score
					score += multiple;
				}
			}
		}
		cout << score << endl;
	}
}

void PrintSpace(void){
	cout << "\n\n\n\n\n\n\n\n\n\n";
}

int main(){
	int menuoption;// = MenuSelect();
	bool exitprogram = false;		// default (of course) to not exiting
	int candcount = 0;
	int votercount = 0;
	char vote[7][100];

	do {
		menuoption = MenuSelect();	// set the menuselection
		switch (menuoption){
			case 1: PrintSpace(); LoadData(vote, candcount,votercount); break;
			case 2: PrintSpace(); PrefSched(vote, candcount, votercount); break;
			case 3: PrintSpace(); Plurality(vote, candcount, votercount); break;
			case 4: PrintSpace(); Borda(vote, candcount, votercount); break;
			case 5: exitprogram = true; break;
			default: cout << "Make another selection.\n\n"; break;
		}
	} while (! exitprogram);

	// Give user an airline goodbye
	cout << "Buh-bye now." << endl;

	return 0;
}

Music Monday: Broken, a cover by Dark Tranquillity

I don’t have much in the way of content for this post, so I’ll just share today’s song. The only thing I don’t like about this song is this part (solo?) in the middle that just goes on WAY too long, and is way too repetitive. I discovered this song through iTunes when I saw a whole album of covers. Some good stuff.

Update:
Including a link to the album, “Covering 20 Years of Extremes“. I want to test my new auto affiliate link plugin.

Luck is a Skill (I knew it!!!)

I just stumbled across this article about luck. As counter intuitive as it may be (to you at least ;) ), it seems luck actually a well-honed skill. That’s right! If you want to be lucky, all it takes is a healthy dose of optimism, and positive thinking.

I’m all for optimism anyway– I just think it feels better. But this guy is not simply telling us to change our attitude if we want to feel happier. He’s talking about the real, tangible results of a paradigm shift1. (1 See The 7 Habits of Highly Effective People“).

Here’s a quote:

I asked a group of lucky and unlucky volunteers to spend a month carrying out exercises designed to help them think and behave like a lucky person. These exercises helped them spot chance opportunities, listen to their intuition, expect to be lucky, and be more resilient to bad luck.

One month later, the volunteers returned and described what had happened. The results were dramatic: 80 per cent of people were now happier, more satisfied with their lives and, perhaps most important of all, luckier.

I swear I’m a case study of this principle! In the last two years my outlook, and in turn my life, have changed so dramatically for the better that I’m considering listing “luck” on my resume as a skill.

This is exactly the sort of thing that The Secret talks about, although it attributes success to “the universe,” which sounds much more mystical. Either way they both contain universal truth that is worth heeding.

So if you don’t feel lucky, then look on the bright side.

UPDATE: Apparently this guy has a book called Luck Factor. (Yes, it’s an affiliate link. I’m feeling lucky. :) )