Toilet Seat Inequality SOLVED!

jackie_chan

I’m not sure about the rest of the World, but in the UK it seems quite prevalent that women will complain if they have to put the toilet seat down before use, and I’ve had many an argument about this with previous girlfriends and now my wife.

Arguments like “it’s just easier for everyone” and “it’s not fair that I should always have to put the seat down” are often used, but instinctively they’ve always seemed wrong. I’ve always felt (and argued) that a fairer system is to just put the seat to whichever position you require, and then leave it as it is, because I was sure this meant generally less fannying about with the seat for all concerned.

And now, through the medium of Java code, I have proven it. Behold:

public class FairnessTest {
     private boolean okayToRun = true;
     private Seat seat;
     private final String SEAT_UP = "UP";
     private final String SEAT_DOWN = "DOWN";
     private final String NEEDS_ONE = "#1";
     private final String NEEDS_TWO = "#2";
     private final Object doorLock = new Object();
     // NOTE: Toggle this boolean to change whether or not seat has to be reset to "DOWN" position, after use
     private boolean seatResetRequired = true;
     
     private int visitTotal = 0;
     private int toggleTotal = 0;
     private int visitTotalMale = 0;
     private int toggleTotalMale = 0;
     private int visitTotalFemale = 0;
     private int toggleTotalFemale = 0;
     
     public static void main(String[] args){
         new FairnessTest();
     }
     
     public FairnessTest(){
         // create the Seat
         seat = new Seat();
         
         // create 2 men and 2 women, and start their behaviour
         new Man("Jeff").start();
         new Man("Bill").start();
         new Woman("Betty").start();
         new Woman("Agnes").start();
         
         // wait 60 seconds on the main thread, then terminate all behaviour
         try {
             Thread.sleep(60000);
         }
         catch (Exception e){}
         okayToRun = false;
         
         // readout results
         System.out.println("");
         System.out.println("RESULTS");
         System.out.println("=======");
         System.out.println("Total Visits: " + visitTotal);
         System.out.println("Total Toggles: " + toggleTotal);
         System.out.println("Toggle percentage: " + (int)(((double)toggleTotal / (double)visitTotal) * 100) + "%");
         System.out.println("Male Total Visits: " + visitTotalMale);
         System.out.println("Male Total Toggles: " + toggleTotalMale);
         System.out.println("Male Toggle percentage: " + (int)(((double)toggleTotalMale / (double)visitTotalMale) * 100) + "%");
         System.out.println("Female Total Visits: " + visitTotalFemale);
         System.out.println("Female Total Toggles: " + toggleTotalFemale);
         System.out.println("Female Toggle percentage: " + (int)(((double)toggleTotalFemale / (double)visitTotalFemale) * 100) + "%");
     }
     
     
     /**
      * INTERNAL CLASSES.
      */

    class Man extends Thread {
         private String name;
         private String needs;
         
         public Man(String name){
             this.name = name;
         }
         
         public String toString(){
             return name;
         }
         
         public void run(){
             while (okayToRun){
                 try {
                     sleep((int)(Math.random() * 10000));
                 }
                 catch (Exception e){}
                 
                 if (okayToRun){
                     synchronized (doorLock) {
                         visitTotal++;
                         visitTotalMale++;
                         
                         System.out.println("");
                         System.out.println(this.toString() + " enters");
                         
                         String currentSeatStatus = seat.getStatus();
                         String requiredSeatStatus = getRequiredSeatStatus();
                         
                         if (!requiredSeatStatus.equals(currentSeatStatus)){
                             toggleTotal++;
                             toggleTotalMale++;
                             seat.toggleStatus();
                             System.out.println(" **" + this.toString() + (requiredSeatStatus.equals(SEAT_UP) ? " raises seat**" : " lowers seat**"));
                         }
                         
                         System.out.println("    " + this.toString() + " uses for " + needs);
                         
                         if (seatResetRequired && seat.getStatus().equals(SEAT_UP)){
                             System.out.println(" **" + this.toString() + " resets seat**");
                             toggleTotal++;
                             toggleTotalMale++;
                             seat.toggleStatus();
                         }
                         
                         System.out.println(this.toString() + " leaves");
                     }
                 }
             }
         }
         
         private String getRequiredSeatStatus(){
             // assuming ratio of 4:1 for 1's and 2's
             if (Math.random() <= 0.2){
                 needs = NEEDS_TWO;
                 return SEAT_DOWN;
             }
             needs = NEEDS_ONE;
             return SEAT_UP;
         }
     }

    class Woman extends Thread {
         private String name;
         private String needs;
         
         public Woman(String name){
             this.name = name;
         }
         
         public String toString(){
             return name;
         }
         
         public void run(){
             while (okayToRun){
                 try {
                     sleep((int)(Math.random() * 10000));
                 }
                 catch (Exception e){}
                 
                 if (okayToRun){
                     synchronized (doorLock) {
                         visitTotal++;
                         visitTotalFemale++;
                         
                         System.out.println("");
                         System.out.println(this.toString() + " enters");
                         
                         String currentSeatStatus = seat.getStatus();
                         String requiredSeatStatus = getRequiredSeatStatus();
                         
                         if (!requiredSeatStatus.equals(currentSeatStatus)){
                             toggleTotal++;
                             toggleTotalFemale++;
                             seat.toggleStatus();
                             System.out.println(" **" + this.toString() + (requiredSeatStatus.equals(SEAT_UP) ? " raises seat**" : " lowers seat**"));
                         }
                         
                         System.out.println("    " + this.toString() + " uses for " + needs);
                         
                         if (seatResetRequired && seat.getStatus().equals(SEAT_UP)){
                             System.out.println(" **" + this.toString() + " resets seat**");
                             toggleTotal++;
                             toggleTotalFemale++;
                             seat.toggleStatus();
                         }
                         
                         System.out.println(this.toString() + " leaves");
                     }
                 }
             }
         }
         
         private String getRequiredSeatStatus(){
             // assuming ratio of 4:1 for 1's and 2's
             if (Math.random() <= 0.2){
                 needs = NEEDS_TWO;
             }
             else {
                 needs = NEEDS_ONE;
             }
             return SEAT_DOWN;
         }
     }
     
     class Seat {
         public String seatStatus = SEAT_DOWN;
         
         public String getStatus(){
             return seatStatus;
         }
         
         public void toggleStatus(){
             seatStatus = seatStatus.equals(SEAT_DOWN) ? SEAT_UP : SEAT_DOWN;
         }
     }
 }

The code looks a bit truncated on here, but just copy and paste it where you need to get it running.

After 6 runs, 3 where the seat is left “as is” and 3 where the seat is always reset to down, the results were as follows:

WITHOUT RESET
-------------

RESULTS
=======
Total Visits: 59
Total Toggles: 27
Toggle percentage: 45%
Male Total Visits: 32
Male Total Toggles: 17
Male Toggle percentage: 53%
Female Total Visits: 27
Female Total Toggles: 10
Female Toggle percentage: 37%

RESULTS
=======
Total Visits: 44
Total Toggles: 25
Toggle percentage: 56%
Male Total Visits: 21
Male Total Toggles: 13
Male Toggle percentage: 61%
Female Total Visits: 23
Female Total Toggles: 12
Female Toggle percentage: 52%

RESULTS
=======
Total Visits: 46
Total Toggles: 26
Toggle percentage: 56%
Male Total Visits: 20
Male Total Toggles: 15
Male Toggle percentage: 75%
Female Total Visits: 26
Female Total Toggles: 11
Female Toggle percentage: 42%


WITH RESET
----------

RESULTS
=======
Total Visits: 41
Total Toggles: 34
Toggle percentage: 82%
Male Total Visits: 21
Male Total Toggles: 34
Male Toggle percentage: 161%
Female Total Visits: 20
Female Total Toggles: 0
Female Toggle percentage: 0%

RESULTS
=======
Total Visits: 51
Total Toggles: 46
Toggle percentage: 90%
Male Total Visits: 28
Male Total Toggles: 46
Male Toggle percentage: 164%
Female Total Visits: 23
Female Total Toggles: 0
Female Toggle percentage: 0%

RESULTS
=======
Total Visits: 51
Total Toggles: 32
Toggle percentage: 62%
Male Total Visits: 27
Male Total Toggles: 32
Male Toggle percentage: 118%
Female Total Visits: 24
Female Total Toggles: 0
Female Toggle percentage: 0%

The results speak for themselves. Even with the “no reset” system, the women still don’t have to alter the seat as much as the blokes. It’s win-win for them.

So gentlemen, leave the seat up when you’ve finished, it’s the right thing to do.

 

TRP

Scaled Images

Just been looking at some simple image scaling in Java.

I’ve done plenty of image scaling in Android lately, but I just thought I’d refresh my memory with Java, so I wrote a very simple class:

Screen Shot 2015-06-18 at 13.23.31

I put it here as an image because the formatting when you copy and paste into WordPress is terrible. Soz.

 

TRP

Command Pattern

command_implementation_-_uml_class_diagram

Definition of a Macro: “An object that contains a symbol, name or key that represents a list of commands, actions or keystrokes”. This is the basis of the Command design pattern.

The Command Pattern encapsulates commands (method calls) in objects, allowing us to issue requests without knowing the requested operation or the requesting object. This pattern provides the options to queue commands, undo/redo actions etc.

Overview

  • Encapsulate a request in an object
  • Allows the parameterization of clients with different requests
  • Allows saving the requests in a queue

The classes participating in the pattern are:

  • Command
    • declares an interface for executing an operation
  • ConcreteCommand
    • extends the Command interface, implementing the Execute method by invoking the corresponding operations on Receiver. It defines a link between the Receiver and the action.
  • Client
    • creates a ConcreteCommand object and sets its receiver
  • Invoker
    • asks the command to carry out the request
  • Receiver
    • knows how to perform the operations

The Client asks for a command to be executed. The Invoker takes the command, encapsulates it and places it in a queue, in case there is something else to do first, and the ConcreteCommand that is in charge of the requested command, sending its result to the Receiver.

I’ve basically nicked all this, word for word, from the source below but it seemed pointless to reword and rework it too much. It’s good info.

 

TRP

source: www.oodesign.com/command-pattern.html

Factory Pattern

Factory Pattern

The Factory Pattern creates objects without exposing the underlying logic to the calling class, which then refers to the newly created object through a common interface.

The advantage of this pattern is that new “products” can be added without changing a single line of code in the framework (the client code that uses the resultant objects).

 

TRP

Singleton Pattern

The Singleton Pattern basically restricts the instantiation of a class to one object.

An very simple example of this is as follows:

    public class Singleton {

        private static Singleton singleton = new Singleton();
        private static double randomNumber = (Math.random() * 100000);

        /* A private Constructor prevents any other
        * class from instantiating.
        */
        private Singleton(){ }

        /* Static ‘instance’ method */
        public static Singleton getInstance() {
            return singleton;
        }

        /* Other methods protected by singleton-ness */
        protected static void demoMethod() {
            System.out.println(“demoMethod for singleton (” + randomNumber + “)”);
        }
    }

    public class SingletonDemo {

        public static void main(String[] args) {
            Singleton tmp = Singleton.getInstance( );
            tmp.demoMethod( );

            Singleton tmp2 = Singleton.getInstance( );
            tmp2.demoMethod( );
        }
    }

The reason we include a random number is to prove that we get the same instance of Singleton whenever we call getInstance().

 

TRP

Observer Pattern

ObserverPattern

So, I’ve been looking at Design Patterns lately, and I’ve decided to document a couple, starting with the Observer Pattern.

The basic gist of it is that you have an “observable” class/interface (in this case Subject implemented as MyTopic) which has, amongst others, the methods register(Observer obj) and notifyObservers().

You then pass in concrete instances of the interface Observer (in this case MyTopicSubscriber) via the subject.register() method, and then – any time the Subject is altered or otherwise interacted with, it can then call notifyObservers() and then – via calls to each of the Observer object’s update() method, everyone in that list of Observers can be informed.

That’s about it, really. Seems simple!

 

TRP

Call Me Back

IMAG0191

I’ve just sketched out the logic of a basic callback mechanism, allowing “code injection” from your main project into a project or .jar file included in its build path – bypassing the undesirable prospect of a circular dependency.

If my writing is too illegible in that image, the basic premise is this:

“LibraryProject” defines an interface “MyCallback”, which declares the method “callback()”. A concrete class within LibraryProject (to give it a name, “LibTestClass”) includes a public “setMyCallback(…)” method which allows a MyCallback object to be passed in.

Within “MainProject”, a class “ExampleCallback” is written, which implements MyCallback from LibraryProject.

Another concrete class within MainProject (“MainTestClass”) will instantiate an ExampleCallback object, and pass it into a LibTestClass instance via the setMyCallback(…) method.

This part is key: The overridden “callback()” method inside ExampleCallback is the code that is eventually injected into (and executed from) LibraryProject when code inside the LibTestClass instance calls {MyCallback}.callback().

That about sums it up I think.

 

TRP