philihp.com

This is how I feel about C

I don’t think C gets enough credit. Sure, C doesn’t love you. C isn’t about love–C is about thrills. C hangs around in the bad part of town. C knows all the gang signs. C has a motorcycle, and wears the leathers everywhere, and never wears a helmet, because that would mess up C’s punked-out hair. C likes to give cops the finger and grin and speed away. Mention that you’d like something, and C will pretend to ignore you; the next day, C will bring you one, no questions asked, and toss it to you with a you-know-you-want-me smirk that makes your heart race. Where did C get it? “It fell off a truck,” C says, putting away the boltcutters. You start to feel like C doesn’t know the meaning of “private” or “protected”: what C wants, C takes. This excites you. C knows how to get you anything but safety. C will give you anything but commitment

In the end, you’ll leave C, not because you want something better, but because you can’t handle the intensity. C says “I’m gonna live fast, die young, and leave a good-looking corpse,” but you know that C can never die, not so long as C is still the fastest thing on the road.

Anonymous on 4chan

Adding Tiles to a Struts 1.3 Project with a Custom Request Processor

In Struts, if you wanted to do funny shenanigans (e.g. override the Roles checking for authorization, or override the ActionForm population to parse a JSON object rather than standard parameters) with the Struts Controller, up until Struts 1.2, you had to extend the Request Processor and configure the Struts ActionServlet to use it instead. This would get rather complicated when you tried to layer multiple custom controllers together, such as with the Validator and the Tiles plugins.

Struts 1.3 changed this behavior. Rather than all of the heavy lifting being offloaded onto the RequestProcessor object by the ActionServlet, instead there’s a chain of commands executed by a class called “ComposableRequestProcessor, and it’s configured by chain-config.xml; which is in the struts-core JAR file. If you want to extend the controller to do out-of-the-ordinary stuff, you’re supposed to copy this file to somewhere else (like /WEB-inF/custom-chain-config.xml) edit it, and configure the ActionServlet to look at it instead like this

<servlet>
 <servlet-name>action</servlet-name>
 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
 <init-param>
  <param-name>config</param-name>
  <param-value>/WEB-INF/struts-config.xml</param-value>
 </init-param>
 <init-param>
  <param-name>chainConfig</param-name>
  <param-value>/WEB-INF/custom-chain-config.xml</param-value>
 </init-param>
</servlet>

The trouble however, is that the Struts Tiles plugin that shipped with 1.3 didn’t change from 1.2. It was written to automatically replace the default RequestProcessor and its chain of command. I’m pretty sure this was supposed to be a convenience, so that to use the Tiles plugin, all you had to do was flip a switch, and it would figure out its own hooks into Struts… because this is how the Struts Tiles plugin works; it essentially overrides and customizes the RequestProcessor so forwards goto it, rather than to some JSP file or somerthing somewhere. You can see how it’s doing this overriding by looking at the method TilesPlugin.initRequestProcessorClass; which is actually a little interesting, because it’s not mucking with any XML. But that’s all you really have to do, usually.

However, and this is why I’m posting this; if you have a custom chain-config.xml already in place that was based on the chain-config.xml in the struts-core JAR, then your ActionForwards going to Tiles layouts aren’t going to lookup correctly. For example, when Struts tries to goto the ActionForward “page.index”, we get the following exception because normally ActionForwards would goto a page like “/index.jsp”.

WARNING: Unhandled exception
java.lang.IllegalArgumentException: Path page.index does not start with a "/" character
	at org.apache.catalina.core.ApplicationContext.getRequestDispatcher(ApplicationContext.java:374)
	at org.apache.catalina.core.ApplicationContextFacade.getRequestDispatcher(ApplicationContextFacade.java:196)
	at org.apache.struts.chain.commands.servlet.PerformForward.handleAsForward(PerformForward.java:107)
	at org.apache.struts.chain.commands.servlet.PerformForward.perform(PerformForward.java:96)
	at org.apache.struts.chain.commands.AbstractPerformForward.execute(AbstractPerformForward.java:54)
	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
	at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
        ...

As far as cryptic errors go, this one is pretty far up there, and unless you actually know how Tiles works, it’s going to be a huge pain to debug. The remedy is actually to base your chain-config.xml file off of Tiles’ own chain-config.xml. And in it you can see how at the end it calls TilesPreProcessor right before it performs the forward.

The Tiles documentation indeed says you need to do this — but hardly anyone ever does, because everything will work unless you customize the request processor; and hardly any books or sites out there will tell you to do it.

This is how I feel about Perl

Good code in perl is fine, but there’s something about bad code in perl
that’s worse than bad code in other languages, something very HP-Lovecraft-
mad-servants-of-the-elder-gods-chattering-in-the-extradimensional-
insect-language kind of bad that makes my head hurt when I have to read
it.

Jish Karoshi on comp.lang.ruby

CSS even/odd row selectors! Finally!

IE9 has been released, and it finally includes the “nth-child” pseudo-selector in CSS! In the past, this has been done on a server side, or with javascript. Now we finally have simple CSS rules for rows in tables that highlight every even or odd row, and it works in every browser without any hacks.

tr:nth-child(odd) {
  background-color: #def;
}
tr:nth-child(even) {
  background-color: #fff;
}

Browser Release Date
IE1 April 16, 1995
IE2 November 22, 1995
IE3 August 13, 1996
IE4 September 15, 1997
IE5 March 18, 1999
IE6 August 27, 2001
IE7 October 18, 2006
IE8 March 19, 2009
IE9 March 14, 2011

Using SAS/OR to solve Sudoku puzzles

I just got back from SAS Global Forum 2011 and heard about this really cool package called SAS/OR (Operations Research).

Within it, there’s a procedure called CLP, which does nothing short of programming voodoo.

The CLP procedure is a finite-domain constraint programming solver for constraint satisfaction
problems (CSPs) with linear, logical, global, and scheduling constraints.

Basically, you tell it your situation, and it tells you a solution. In the following example (pulled straight from the documentation), we tell it what the final solution of a sudoku would look like, and we give it a puzzle. Then it solves it for us.

proc clp out=outdata;
	/* Define variables */
	var (X_1_1-X_1_9) = [1,9];
	var (X_2_1-X_2_9) = [1,9];
	var (X_3_1-X_3_9) = [1,9];
	var (X_4_1-X_4_9) = [1,9];
	var (X_5_1-X_5_9) = [1,9];
	var (X_6_1-X_6_9) = [1,9];
	var (X_7_1-X_7_9) = [1,9];
	var (X_8_1-X_8_9) = [1,9];
	var (X_9_1-X_9_9) = [1,9];
	/* Tell PROC CLP that all rows must be different */
	alldiff(X_1_1-X_1_9);
	alldiff(X_2_1-X_2_9);
	alldiff(X_3_1-X_3_9);
	alldiff(X_4_1-X_4_9);
	alldiff(X_5_1-X_5_9);
	alldiff(X_6_1-X_6_9);
	alldiff(X_7_1-X_7_9);
	alldiff(X_8_1-X_8_9);
	alldiff(X_9_1-X_9_9);
	/* Tell PROC CLP that all columns must be different */
	alldiff(X_1_1 X_2_1 X_3_1 X_4_1 X_5_1 X_6_1 X_7_1 X_8_1 X_9_1);
	alldiff(X_1_2 X_2_2 X_3_2 X_4_2 X_5_2 X_6_2 X_7_2 X_8_2 X_9_2);
	alldiff(X_1_3 X_2_3 X_3_3 X_4_3 X_5_3 X_6_3 X_7_3 X_8_3 X_9_3);
	alldiff(X_1_4 X_2_4 X_3_4 X_4_4 X_5_4 X_6_4 X_7_4 X_8_4 X_9_4);
	alldiff(X_1_5 X_2_5 X_3_5 X_4_5 X_5_5 X_6_5 X_7_5 X_8_5 X_9_5);
	alldiff(X_1_6 X_2_6 X_3_6 X_4_6 X_5_6 X_6_6 X_7_6 X_8_6 X_9_6);
	alldiff(X_1_7 X_2_7 X_3_7 X_4_7 X_5_7 X_6_7 X_7_7 X_8_7 X_9_7);
	alldiff(X_1_8 X_2_8 X_3_8 X_4_8 X_5_8 X_6_8 X_7_8 X_8_8 X_9_8);
	alldiff(X_1_9 X_2_9 X_3_9 X_4_9 X_5_9 X_6_9 X_7_9 X_8_9 X_9_9);
	/* Tell PROC CLP that all clusters must be different */
	alldiff(X_1_1 X_1_2 X_1_3 X_2_1 X_2_2 X_2_3 X_3_1 X_3_2 X_3_3);
	alldiff(X_1_4 X_1_5 X_1_6 X_2_4 X_2_5 X_2_6 X_3_4 X_3_5 X_3_6);
	alldiff(X_1_7 X_1_8 X_1_9 X_2_7 X_2_8 X_2_9 X_3_7 X_3_8 X_3_9);
	alldiff(X_4_1 X_4_2 X_4_3 X_5_1 X_5_2 X_5_3 X_6_1 X_6_2 X_6_3);
	alldiff(X_4_4 X_4_5 X_4_6 X_5_4 X_5_5 X_5_6 X_6_4 X_6_5 X_6_6);
	alldiff(X_4_7 X_4_8 X_4_9 X_5_7 X_5_8 X_5_9 X_6_7 X_6_8 X_6_9);
	alldiff(X_7_1 X_7_2 X_7_3 X_8_1 X_8_2 X_8_3 X_9_1 X_9_2 X_9_3);
	alldiff(X_7_4 X_7_5 X_7_6 X_8_4 X_8_5 X_8_6 X_9_4 X_9_5 X_9_6);
	alldiff(X_7_7 X_7_8 X_7_9 X_8_7 X_8_8 X_8_9 X_9_7 X_9_8 X_9_9);
 
	/* Linear conditions... (starting point) */
	lincon X_1_3 = 5;
	lincon X_1_6 = 7;
	lincon X_1_9 = 1;
	lincon X_2_2 = 7;
	lincon X_2_5 = 9;
	lincon X_2_8 = 3;
	lincon X_3_4 = 6;
	lincon X_4_3 = 3;
	lincon X_4_6 = 1;
	lincon X_4_9 = 5;
	lincon X_5_2 = 9;
	lincon X_5_5 = 8;
	lincon X_5_8 = 2;
	lincon X_6_1 = 1;
	lincon X_6_4 = 2;
	lincon X_6_7 = 4;
	lincon X_7_3 = 2;
	lincon X_7_6 = 6;
	lincon X_7_9 = 9;
	lincon X_8_5 = 4;
	lincon X_8_8 = 8;
	lincon X_9_1 = 8;
	lincon X_9_4 = 1;
	lincon X_9_7 = 5;
run;
NOTE: Variable selection strategy: MINR.
NOTE: Value selection strategy: MIN.
NOTE: Preprocessing: ON
NOTE: Number of ALLDIFF constraints: 27.
NOTE: Number of LINEAR constraints: 24.
NOTE: Total number of arrays: 0.
NOTE: Total number of variables: 81.
NOTE: Total number of constraints: 51.
NOTE: Required number of solutions found (1).
NOTE: The data set WORK.OUTDATA has 1 observations and 81 variables.
NOTE: PROCEDURE CLP used (Total process time):
      real time           0.05 seconds
      cpu time            0.04 seconds
 
 
STATUS=OK SOLUTION_STATUS=SOLN_LIMIT_REACHED SOLUTIONS_FOUND=1 SOLUTION_TIME=0.00
X_1_1=9 X_1_2=8 X_1_3=5 X_1_4=3 X_1_5=2 X_1_6=7 X_1_7=6 X_1_8=4 X_1_9=1
X_2_1=6 X_2_2=7 X_2_3=1 X_2_4=5 X_2_5=9 X_2_6=4 X_2_7=2 X_2_8=3 X_2_9=8
X_3_1=3 X_3_2=2 X_3_3=4 X_3_4=6 X_3_5=1 X_3_6=8 X_3_7=9 X_3_8=5 X_3_9=7
X_4_1=2 X_4_2=4 X_4_3=3 X_4_4=7 X_4_5=6 X_4_6=1 X_4_7=8 X_4_8=9 X_4_9=5
X_5_1=5 X_5_2=9 X_5_3=7 X_5_4=4 X_5_5=8 X_5_6=3 X_5_7=1 X_5_8=2 X_5_9=6
X_6_1=1 X_6_2=6 X_6_3=8 X_6_4=2 X_6_5=5 X_6_6=9 X_6_7=4 X_6_8=7 X_6_9=3
X_7_1=4 X_7_2=5 X_7_3=2 X_7_4=8 X_7_5=3 X_7_6=6 X_7_7=7 X_7_8=1 X_7_9=9
X_8_1=7 X_8_2=1 X_8_3=6 X_8_4=9 X_8_5=4 X_8_6=5 X_8_7=3 X_8_8=8 X_8_9=2
X_9_1=8 X_9_2=3 X_9_3=9 X_9_4=1 X_9_5=7 X_9_6=2 X_9_7=5 X_9_8=6 X_9_9=4

But it gets even cooler! We can use the FINDALLSOLNS option and it will tell us all the possible solutions to the puzzle…

STATUS=OK SOLUTION_STATUS=ALL_SOLUTIONS SOLUTIONS_FOUND=125 SOLUTION_TIME=0.08

And by browsing the output, we can know that there are only 3 possible solutions where row 9, column 3 is a ’6′, which makes for a much more difficult puzzle.

STATUS=OK SOLUTION_STATUS=ALL_SOLUTIONS SOLUTIONS_FOUND=3 SOLUTION_TIME=0.00

Euler’s Identity; e^(i*pi)=-1

ExpIPi

I really don’t understand why this isn’t taught to every first year calculus class in the country. It’s so elegant, and complex, and beautiful. An imaginary number combined with an irrational number combined with natural logarithm hocus pocus equals an integer!
math

Things I Learned from Wiring a Car Stereo

S2000 Wiring Diagram

S2000 Wiring Diagram

So I just finished installing a car stereo into my car. I wanted to do it myself to learn as much a possible. This post is to share bits of information that were previously buried on message boards, or were myths that car audio shops had previously told me (or debunked for me).

DISCLAIMER: I’m not a professional, any of this could be false, I just want to share what I now know.

Running power

  • The entire chassis is grounded. This is why you remove the black contact first when installing a battery; you don’t want the red contact to brush up against the chassis and cause a short.
  • Shorts are bad, because resistance approaches zero, and Voltage=Current*Resistance. Voltage is a constant 12 volts, and all that current gets converted to heat (fire)
  • Install fuses as close to the battery as possible. This reduces the risk of a short by accidentally touching the red wire to the chassis.
  • Your amp should have fuses on it (e.g. mine each had two 25A fuses). Add up the total amperage, and use a fuse near the battery slightly higher than this (I used a 60A fuse going to each amp).
  • Battery power to the amps is DC, while lines going from the amps to the speakers is AC. This is why you need expensive high gauge wire for power, but speaker wire can be relatively thin in comparison.
  • It is a half-myth that electricity travels on the surface of the wire. This is only true for AC power, and should be most current travels on the surface, not all; so high thread-count for AC is important and not for DC. It is called the skin effect, and happens because at every point in a cross section of a wire, magnetic flux is inducing back EMF causing resistance, and the center of the wire is subject to highest amount of this. DC has no alternating flux, so this doesn’t happen, and resistance is even across the cross section of the wire. However high threadcount wire can be bent more before breaking, so it’s easier to snake around corners; that’s really the only advantage of it for power wire.
  • Avoid cheap alloy wires that are copper-coated. You can tell by looking at the ends of the wires where it is cut; it should be solid copper. Pure copper wire is fairly heavy too. If you get this wire, make sure it has low resistance.
  • At high amperages, the resistance of the power wire becomes significant. Calculate amps by watts = amps * volts (where volts is 12). If too much current goes through, too much heat is created which melts the insulation off and the wire touches the chassis which is grounded and causes a short. Since you installed a fuse, it will blow rather than your car catching on fire.
  • When grounding the amps, use the same gauge you used for running power. The same amount of current flows through them. Since the chassis is grounded, they can be terminated by bolting these to the chassis. Sand down the area where they’re bolted, because it’s probably painted (to stop rust and corrosion).

Amps and Speakers

  • Class D amps are good for subwoofers. They are generally 2/1 channel, which means they have 2 channels, but you can “bridge” the two together to get twice the boost for one channel.
  • Ignore the “max” watts of a speaker or amp, and only pay attention to RMS (Root Mean Square), which is essentially the “average” power of a speaker or amp. Don’t buy speakers who don’t list this, unless they are free, which in that case they are probably half of the “rated” power.
  • Pair your amp to your speakers; which means get an amp with slightly more average power than the speakers.
  • It is better to have underpowered speakers than an underpowered amp. If your volume goes too high the amp will start clipping at peaks and troughs. At these points, pure DC is sent over the line rather than AC. DC creates heat which burns out the coils in your speakers. This is how speakers are usually blown.
  • Do not run signal wires parallel to power. If they cross, make it happen perpendicularly. Electrical Induction is a magical thing that you should avoid because it makes phantom buzzing in your music.

Headunits

  • This is the thing that goes in the dash, and is usually the flashiest and most superficial of things.
  • All Alpine headunits have RCA plugs out that go to the amp. This is not always the case for other makers.
  • There is a blue wire in the wiring harness somewhere; this should be run to the “remote” terminal on your amps. It is how the car tells the stereo that the car is on (rather than parked idle); without this your amps would always be on, and always be draining your battery. It’s very low current, so really thin wire will suffice.

Crossovers

  • They separate high frequencies and low frequencies.
  • These are electrically very simple things. You can build them yourself if you can solder. Don’t spend a lot of money on them.

Excel 2010′s Default AutoRecover Location

And so the only thing you need to know about Excel’s AutoRecover is this: the default path for Excel is:

C:UsersyouApplication DataMicrosoftExcel

Keep in mind, Application Data is usually a hidden folder, so you might not see it. It is still there.

Mode 7, and How to Fake Depth in 2d

The term Mode 7 originated on the Super NES video game console, on which it describes a simple texture mapping graphics mode that allows a background layer to be rotated and scaled. By modifying the scaling and positioning of the layer on a scanline-by-scanline basis, a simple perspective effect can be applied, transforming the layer into a 2-dimensional horizontal texture-mapped plane that trades height for depth. Thus, an impression of 3-dimensional graphics is achieved.

wikipedia.org/wiki/Mode_7

Basically, for lines on the screen, when they’re at the top, scale the texture smaller. When they’re near the bottom, scale the texture bigger.

Immediately makes me remember Super Mario Kart and F-Zero. This is how they did the fake 3d perspective of the ground before titles like Star Fox came out;and it also explains why the barriers on the racetracks always appeared flat, whereas in games like Stunt Race FX, the barriers were solid. What I didn’t realize, was that Final Fantasy VI also used this trick for the world map. Neat.

EAGLE Library for 4-Digit 7-Segment LED Display

EAGLE Screenshot

I made this EAGLE library for the LTC-4027JR 4-digit common cathode 7-segment super bright red LED clock display. As of right now, they’re $3.96 on Digikey.com. Since each digit has a common cathode, I have to multiplex the digits to display numbers larger than 9. The library can be used in EAGLE to make schematics and board designs.

LTC-4727JR.lbr

DISCLAIMER: I don’t know what the hell I’m doing. I’m just really proud of this, and wanted to share it with the internet.