Tuesday, February 25, 2014

Reverse Proxy with url rewrite.

I have been working on a project where I needed two two web servers to act like they wore on the same domain.  In production this will probably be done with a reverse proxy like hapoxy, but for my dev box I need something that was windows friendly and that I could setup with out much effort for any of my team.

Turns out that node can do this and it's very easy to do. In just 12 lines of my own code I had a reverse proxy that would do url rewriting. Check it out.





Monday, December 16, 2013

Fun In google drive

This is a useful little function for google docs spread sheet

=TO_DATE(TO_PURE_NUMBER(A2) +TO_PURE_NUMBER("0:10:00"))

Yes you can use it to give your self a spread sheet with a new time every 10 min with out having to write it out for every line.

Tuesday, January 22, 2013

Functional programming in javascript


Over the last several months I have been working on an article that talks about why you should stop using for loops and use map, each, and reduce to manipulate your data.  They increase the readability of code especially if you name the functions being applied to the collection of data.  I have never finished this article I get caught up in the details and it never flows the way I want it to. 

Today I did find some articles that explain why I prefer functional programming ides to using a traditional for loop,  these articles come form the the developers at Salsita Software.

Check them out: 

Friday, January 11, 2013

Taking it out is better


As developers we spend a lot of time writing code.  Most of this is adding new features to a product, the rest is spent changing a product to use a new API.  Seldom is it to go into a system and clean up all the relics lying around in the code base.

When you switch to the new shiny API you seldom remove the old code files that talked to the old API because you may need to switch back to the old API in a real hurry.  You comment out the code or put in a conditional statement thinking that you will come back and remove them later on when you aren't so busy. This is all well and good except for one thing you are always busy. 

Over time these code relics pile up and pollute a code base.  Remember the developer that put in the "if statement" on line 12 of foo.cs?  Well he took a new job and now no one knows why that relic exists. The knowledge left with that developers and now we have a liability.  Most developers are willing to let sleeping dogs lie.  If everything is working don't make changes to the code because change means bugs and bugs mean more work.


Not cleaning up code over time causes more work.  You may have unit tests that were written against those old logic branches that are now invalid and out of date.  They could be a red herring in trying to figure out real problems in the code base.  The worst part about this is that it can be prevented with just a little work when you are changing the code.

Take the time to remove the code that is no longer needed.  If you need to roll back to the old way of doing things you use your source control to get the code back.  Take the time to prune useless unit tests.  If a test is not meaningful either change it so it is or get rid of it.  Just by doing these simple things code can be made so much easier to maintain and update over time. 

Saturday, January 5, 2013

deep copy in javascript

One of the things about javascript I don't like is that there is not a simple way to copy an object literal so you don't have side effects when making updates to an object. this script show how I got around this. There is alos a fiddle as well which can be found here

Thursday, November 15, 2012

little bit of javascirpt fun (also know as why this sucks)

A couple weeks ago I was working with a couple developers who didn't understand why I hated prototype in javasciprt.  It's not that I don't think it has uses it's just that if you are using prototype you are probably doing it wrong.  I created this little fiddle to show them where the problems start to happen.

http://jsfiddle.net/phlik/Uv3Sg/

Tuesday, September 18, 2012

Javascript string replacing

I spend a lot of time working in JavaScript.  I also find that I spend a lot of time replacing text in strings in this language.  Most of the time this can be done easily by using a good templating system. When you are working with localization systems, you can't rely on templating.

My first attempt at string replace was:
var stamp = function(template, tag, value){
    return template.replace('{'+ tag + '}', value);
};

This was a very simple attempt and wasn't very good.  It has a lot of problems. Top of the list is it will not get every instance of the tag in the string. You end up having to call stamp several times to replace the same thing.  So I set out to fix this problem.  I found you could use regular expressions to do this kind of thing.  I built out this simple function to do the work.
var stampValues = function (template, replacements) {
    for (var tag in replacements) {
        var reg = new RegExp('\{' + tag + '\}', 'g');
        template = template.replace(reg, replacements[tag]);
    }
    return template;
};

It's much better than the above one because it gets all the tags in the string. It's actually much better than any other code I have tried but more on that later.

The next version looked like this.  It uses underscore to do the flow control because each is better than "for" -- right?
var stampValuesEx0 = function (template, replacements) {
    _(replacements).each(function (value, tag) {
        var reg = new RegExp('\{' + tag + '\}', 'g');
        template = template.replace(reg, value);
    });
    return template;
};

It's not. It's slower.  Not noticeably slower but when you put a timer to it the stampValues is faster.

After looking at this I realized I was doing the Regular expression incorrectly. I could change the way I did it and probably get more speed out of it.  So I built this . . .
var stampValuesEx2 = function (template, replacements) {
    var setValues = (function () {
        var translateReg = /{\w+}/g;
        var cleanup = /[{}]/g;
        return function (s) {
            return (s.replace(translateReg, function (match) {
                return replacements[match.replace(cleanup, '')];
            }));
        };
    })();
    return setValues(template);
}

And It SUCKS.  It's slow; it takes double the time of the stampValues function.  There are a few things you can do to speed it up.  You can build out a closure with the regular expressions already in them this actually helped a lot. It cuts about 1/3 of the execution time.  That version looks like this:
var stampValuesEx3 = (function () {
    var translateReg = /{\w+}/g;
    var cleanup = /[{}]/g;
    return function (template, replacements) {
        return (template.replace(translateReg, function (match) {
            return replacements[match.replace(cleanup, '')];
        }));
    }
})();
It still not as fast as stampValues but it is faster than other attempts I have made.

In short I ended up using stampValues for my string replace function.

The code I used to test all these functions can be found at here take a look. If you have examples that you think are better or faster I would be interested in seeing them.


Thursday, March 22, 2012

String replace the better way.

This last week I have been working on making my team project at work run better on ie 7.  Usually that would mean that I spent all my time fixing styles, but there are better people then me at that.  So for me the project was getting rid of the scrpt is running two long errors.  The app I work on is very JavaScript heavy.  One of the worst offending functions I had found was the following:

function clean(word) {
        if (word) {
            
            return word.toLowerCase().
                replace(/\s/gi, "").                
                replace(/[àáâãäå]/gi, "a").
                replace(/æ/gi, "ae").
                replace(/ç/gi, "c").
                replace(/[èéêë]/gi, "e").
                replace(/[ìíîï]/gi, "i").
                replace(/ñ/gi, "n").
                replace(/[òóôõö]/gi, "o").
                replace(/œ/gi, "oe").
                replace(/[ùúûü]/gi, "u").
                replace(/[ýÿ]/gi, "y").
                replace(/\W/gi, "");
        } else {
            return word;
        }
    }

Which is a very brute force way of cleaning up strings for searching.  It was the most expensive call in our system.  With a little work it was changed to the following. 

var removeAccents = (function () {
        var translateReg = /[àáâãäåæçèéêëìíîïñòóôõöœùúûüýÿ]/g;
        var translate = {
            "à""a""á""a""â""a""ã""a""ä""a",
            "å""a""æ""ae""ç""ç""è""e""é""e",
            "ê""e""ë""e""ì""i""í""i""î""i",
            "ï""i""ñ""n""ò""o""ó""o""ô""o",
            "õ""o""ö""o""œ""oe""ù""u""ú""u",
            "û""u""ü""u""ý""y""ÿ""y"
        };
        return function(s) {
            return (s.replace(translateReg, function(match) {
                return translate[match];
            }));
        };
    })();
 
    function clean(word) {
        if (word) {
            return removeAccents(word.toLowerCase().replace(/\s/gi, "").replace(/\W/gi, ""));
        } else {
            return word;
        }
    }

For a massive boost in performance.




Thursday, January 19, 2012

Failings of the Unix Commodity

Imagine if you will a city with an array of transportation systems.  The most popular transportation system is a personal helicopter.  A home can have dozens of automated helicopters, each built to go fly to a single place and back.  Very little knowledge is needed to operate these helicopters and traveling with them is rather convenient: You don't have to wait for traffic lights or wind around with a road.  You just hop in, the helicopter takes the absolutely most direct route to your destination, and you hop out.

People have grown quite accustomed to having large garages in this city where they keep little armadas of these specialized aircraft; one for going to the supermarket, one for going to the mall, one for going to work, one for going to school, one for going to night clubs, one to cruise around town, and so on.  Hop in, push the "Start" button and you're on your way!

In order to keep selling these helicopters to consumers, manufacturers have been adding luxurious features.  It began with cup holders and grew into hot tubs, projector screens, and all other sorts of amenities to make the flight more pleasant.  While these luxuries do add weight that slows the helicopters down, people don't really notice because of all the fun they're having.

Because these helicopters blindly take the most direct routes to their destinations, crashes are not unheard of.  Some manufacturers try to avoid crashes between two of their own helicopters but that doesn't really do much for the overall aviation safety.

Earlier-on in their history, these helicopters were infamous for their propensity to have mid-air collisions, landing mishaps, and the like.  In spite of all the damage this incoherent method of transportation has caused, you can't argue with the billions of dollars the flying hot tubs have raked in.

While it is true that these helicopters can only travel to certain places, this is largely mitigated by the fact that people are willing to make many varieties of helicopters.  Most helicopter riders only really care to go to the most popular shopping centers and movie theaters anyway so they're quite content with the selection.

The other major mode of transportation is the local subway system.  This series of subterranean tracks is dark, damp and noisy.  It's inconvenient -- requiring you to know a schedule and how trains connect in order to really get anywhere.  It usually involves a lot of indirection as you connect to various stations and hop between different lines to get to your destination.

Those who prefer the subway system are proud of how low their expenses are and how few people actually get hurt by their transit system.  They have experts dedicated to maintaining and fine-tuning the whole transit system to make sure that every train arrives on time with as few surprises as possible.

Subway workers and users get along well.  They have a thriving subculture in their subway.  They all know each other and were always eager to exchange ideas about anything but especially about how they could make their subway better.

Many of the riders are also share-holders in the subway.  They take the money they save from having such an inexpensive transit system and invest it into expanding and refining it.  As a result, there is no part of the city that is more than a mile from the nearest subway station.  While walking to the subway station is a little bit of work, it is manageable and subway drivers tend to be fit and capable of the trek.

With a subway pass (that costs less than a tenth of the insurance premiums that most pay for their helicopters) and a good understanding of the subway system, subway passengers can get anywhere they'd like to go.  They see parts of the city that may be beneath the notice of helicopter riders because nobody makes aircraft that fly there.  These subway riders are totally content to trade some convenience for this kind of freedom; there are no prescribed ways or places to travel.  There is only a system that helps you get anywhere.

Helicopter riders feel like fish out of water when they enter the subway.  They enter the train and start looking for the massaging recliner seats but they find only stiff benches.  They get confused by the unspoken need to pay attention and know whether or not a stop is at the destination.  They are absolutely horrified about the idea of having to walk anywhere -- thinking that when the vehicle stops, the journey should be totally over.  When buried in a tunnel, they feel incapable of knowing where they are or what direction they want to be going.  In fact, they feel annoyed that they have to even know anything about direction.

When I was still in diapers, there were two kinds of computers around: The home desktop and the mainframe.  Home desktops were like a garage full of the Helicopters above: Emphasizing personal convenience and mass-marketability at the cost of stability and long-term maintainability.  Mainframes were like the Subway described above:  Sacrificing personal convenience and ease-of-use in exchange for having a robust, reliable, versatile system that can service the needs of many people at once.

I know I'm going to get crap if I don't mention Linux so...

As the years went by in this city, helicopter manufacturers got adventurous.  They tried to emulate admirable traits of the subway system; sometimes consciously, sometimes not.  They started making helicopters that could fly to multiple destinations.  They started making hybrid airplane-helicopter craft that could take you greater distances than just a helicopter could.  They introduced parachutes to keep helicopters from crashing into the ground in a massive conflagration of doom, and they started teaching riders to jump out of one helicopter and into another in a highly dangerous attempt at getting people places faster without having to buy more helicopters.

Meanwhile, others who admired the solid engineering of the subway system tried to emulate its strengths.  A group of volunteers paved an expansive road system on the ground that roughly resembled the subway tunnels beneath them.  Other volunteers built custom cars to drive on this road that had some of the conveniences you find in personal helicopters.  

These automobile drivers included crazy hippies that believed that asphalt was implicitly morally superior to flying as well as some entrepreneurs who hoped there would be a rising car market like there had been a helicopter market.  Some still just liked the penguin logo that was painted onto the cars.

While driver neglect could cause crashes on these roads and they were still more common than in the subway, the consequences of these crashes weren't quite as catastrophic as the airborne equivalents and so it was generally believed to be better.

This is a story that many are familiar with.  But there's actually a lot more to it than that.  Years before the automobile was introduced, there emerged another subway imitation in town.  

Some entrepreneurial souls looked at the great efficiency and usefulness of the subway and decided to try making rail travel a tradable commodity.  They prefabricated railways that could be flown in and dropped on top of a neighborhood for an instant railway transit system.  This process was naturally expensive so only the wealthiest districts could afford such a thing.

The enormous template of rail tried hard to look like the layout of the subway system.  But building such a system in such a different circumstance is hard.  When transporting this massive pretzel of track, it would often bend and warp under its own weight and had to be reshaped to fit the terrain.  After the track was finally set in place, it usually didn't resemble the subway it was intended to emulate.

Three major companies rose as providers of trolley networks.  Each had their own ideas as to what a track system should look like and how the trolley cars should behave.  Each track would be just similar enough that a passenger could make a few safe assumptions about the schedules and directions of certain lines.  And each would have its own "gotchas" that made expertise in one neighborhood's track not fully transferable to another.

The lack of standardization between all trolley systems made it incredibly difficult for some to navigate -- even those who had grown accustomed to the subway system were not quite at home on this surface railway.  

Because the companies that made these tracks were more interested in manufacturing efficiency than in usage efficiency, trolleys were eventually written off as a cute anachronism rather than a real transit system.  The purported savings of using such a system simply weren't there.  What's more, because these trolleys purported themselves to be the same as the subway system, whatever bad reputation they'd accrued was shared with the subways.

Those who had sunk the great amounts of money into buying trolley systems were stuck with them and tried to make do with what they had but no new buyers were lining up.

Trolley companies eventually got to the point where they made all their money selling repair and maintenance services to people who'd previously purchased trolley systems from them.

Some tried to add propeller blades to their trolley cars; thinking this could attract some helicopter-style revenue.  Other companies tried making their cars bigger or faster to see if that would attract neighborhoods to their wares.  

In spite of all their efforts, the trolley companies weren't getting the kind of money they wanted.  Their attempts at mutating with market demands only made whatever rail templates they did sell even less cohesive than before.

One trolley manufacturer decided to shift efforts toward building accessories for helicopters.  Another transformed its trolleys into industrial freight trains.  The last fumbled around for a while until the penguin cars showed up.  They eagerly jumped on the bandwagon and have been trying to transform their own track into paved roads since.  As soon as they saw the cars weren't just a fad, they started pulling parts out of their disheveled trolley cars and plugging them into the automobiles, hoping more than anything that they could turn it into a solid business plan.

This last company still has lingering segments of track with disheveled cars sputtering about it.  This slow energy hog of a transit system is a glorious testament of the hubris of the trolley industry which presumed they could prefabricate the emergent brilliance of a peer-reviewed, actively used, actively maintained transit system.

Some took this lesson from the trolley industry as evidence that rail travel was all together flawed or that the mistakes of the trolley were the mistakes of the subway as well.  Some even believed that the pitfalls of the trolley model were a problem with all non-aeronautic travel --- making it easy to dismiss the cars and their pavement when those started cropping up.

Today, the trolley is one of the more clumsy, unreliable forms of transportation there is.  Even the messy helicopter industry has managed to fumble their way into some best practices that mitigate their system's shortcomings.  As helicopters grow to more closely resemble the subway system beneath them, they brag about how novel and illustrious their inventions are and they mock the rails that they see beneath them.

Their mockery is not entirely unfounded.  If your only exposure to computing systems were the home desktop and the commercial Unix system, it makes perfect sense why you would prefer your squadron of helicopters.

Wednesday, January 18, 2012

jQuery how I love you.

So I had a problem today where I needed to be able to tell if a JavaScript object was empty.  I spent 10 minuets  Googleing for a consice soluction then I went to jQuery util page on a whim and the answer was there.

http://api.jquery.com/jQuery.isEmptyObject/

With just one call the library will tell me if it has data.  Thanks to the people that build such cool tools for me to use.

Friday, January 13, 2012

Benchmarking arithmetic

Got curious so I decided to see how quickly and accurately some arithmetic gets done in various environments. Results below.

[ishpeck@slcatedjamu ~]$ time dc -e "16384d^p"
113837518811535904250072068341232590877598871955010488951192642300792\
621302625312821980719831387362324936714246794526258573039676337010858\
828763430793585922853616976807646165532533059489556150449708988141578\
442943112023447213983043116092849446398990980402342632274314814328953\
404819192156219054837263740293206244418473178404516135133213244063518\
784562296023799090475839668510215390134010117698262576769574042814029\
529033278052184274508131740701273566100706819850632337113494857562098\
320151217292158833266370707127916108421901433177514694034750917722728
... ....
218238270074739736264157780272832032578594361150434678340392480113080\
089703735801591153586235927851796939292373259062814173277075113674401\
829043044144045490928371875112748010711233174142910835089303346849145\
895484745236306027347877637526426501080516036812222087305078640639225\
541848209795509140539016236258676383295890570846220185368800472374864\
023572119859359115185919085597104610288583655001397080304511835993974\
191673243089264458895016889710034575213135566915400700972672256581021\
999134594756634350940758242683390117111624193719460587302044176159214\
609746781781933047509937334480699072619539011846151062186574802048674\
92382202923258637344388123757033376532121188827136

real 0m1.167s
user 0m0.283s
sys 0m0.003s



dc surprised me with its slowness until I realized it was throwing those backslashes in there. That can eat up some time.

[ishpeck@slcatedjamu ~]$ time python -c "print 16384 ** 16384"
1138375188115359042500720683412325908775988719550104889511926423007926213026253128219807198313873623249367142467945262585730396763370108588287634307935859228536169768076461655325330594895561504497089881415784429431120234472139830431160928494463989909804023426322743148143289534048191921562190548372637402932062444184731784045161351332132440635187845622960237990904758396685102153901340101176982625767695740428140295290332780521842745081317407012735661007068198506323371134948575620983201512172921588332663707071279161084219014331775146940347509177227281385333933210897869224188603686168680892745382927717262582865116798735382574696365796311299351046728260094290719606736072012259117111400667629363151930588541659099143747134721613089069740776235687657534765557725361993289329394049820885278902800491606809630123223601804037635379024208423418856532333180705506732367579643586252181430162147604245508970283612154605179099342622822975114534462339240221466716903857275803280366341678962977346051289393798425922859136969165217554566247811263669128403448140287396494805411846462566580026934215636853835525602451004242548897751439534340759663617153864418706583169642432738589331305934295186834298433853228606541975022545265261045793253180106547809428350799194427853647105017781506127477182293624210259930919849611849204841346064260162960557828534199134070897721151924
... ...
703704366990068353216089737426366069381491347684599380093222610835917961800770781409200926729603012036399122612354223297965849193568220166221823827007473973626415778027283203257859436115043467834039248011308008970373580159115358623592785179693929237325906281417327707511367440182904304414404549092837187511274801071123317414291083508930334684914589548474523630602734787763752642650108051603681222208730507864063922554184820979550914053901623625867638329589057084622018536880047237486402357211985935911518591908559710461028858365500139708030451183599397419167324308926445889501688971003457521313556691540070097267225658102199913459475663435094075824268339011711162419371946058730204417615921460974678178193304750993733448069907261953901184615106218657480204867492382202923258637344388123757033376532121188827136

real 0m0.789s
user 0m0.203s
sys 0m0.010s


Intrepid old Python has some nice optimization to help eek out those fractions of a second.

[ishpeck@slcatedjamu ~]$ time clisp -x "(expt 16384 16384)"
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ `+' / I 8 8 8 8 8 8
\ `-+-' / 8 8 8 ooooo 8oooo
`-__|__-' 8 8 8 8 8
| 8 o 8 8 o 8 8
------+------ ooooo 8oooooo ooo8ooo ooooo 8

Welcome to GNU CLISP 2.49 (2010-07-07)

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

1138375188115359042500720683412325908775988719550104889511926423007926213026253128219807198313873623249367142467945262585730396763370108588287634307935859228536169768076461655325330594895561504497089881415784429431120234472139830431160928494463989909804023426322743148143289534048191921562190548372637402932062444184731784045161351332132440635187845622960237990904758396685102153901340101176982625767
... ...
7414291083508930334684914589548474523630602734787763752642650108051603681222208730507864063922554184820979550914053901623625867638329589057084622018536880047237486402357211985935911518591908559710461028858365500139708030451183599397419167324308926445889501688971003457521313556691540070097267225658102199913459475663435094075824268339011711162419371946058730204417615921460974678178193304750993733448069907261953901184615106218657480204867492382202923258637344388123757033376532121188827136
Bye.

real 0m1.262s
user 0m0.393s
sys 0m0.007s


It surprised me how much slower Common was here. Doesn't help that it clutters the display with all that junk, either.

[ishpeck@slcatedjamu random_scripts]$ time csharp -e "Console.WriteLine(Math.Pow(16384, 16384));"
Infinity

real 0m0.282s
user 0m0.257s
sys 0m0.033s


I don't know what I did wrong here... I mean, besides trusting a statically typed language to know what to do with so huge a number.

[ishpeck@slcatedjamu ~]$ time newlisp -e "(pow 16384 16384)"
inf

real 0m0.003s
user 0m0.000s
sys 0m0.000s


LAWL! Infinity!

[ishpeck@slcatedjamu ~]$ time echo "16384 ^ 16384" | ghci
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> 11383751881153590425007206834123259087759887195501048895119264230079262130262531282198071983138736232493671424679452625857303967633701085882876343079358592285361697680764616553253305948955615044970898814157844294311202344721398304311609284944639899098040234263227431481432895340481919215621905483726374029320624441847317840451613513321324406351878456229602379909047583966851021539013401011769826257676957404281402952903327805218427450813174070127356610070681985063233711349485756209832015121729215883326637070712791610842190143317751469403475091772272813853339332108978692241886036861686808927453829277172625828651167987353825746963657963112993510467282600942907196067360720122591171114006676293631519305885416590991437471347216130890697407762356876575347655577253619932893293940498208852789028004916068096301232236018040376353790242084234188565323331807055067323675796435862521814301621476042455089702836121546051790993426228229751145344623392402214667169038572758032803663416789629773460512893937984259228591369691652175545662478112636691284034481402873964948054118464625665800269342156368538355256024510042425488977514395343407596636171538644187065831696424327385893313059342951868342984338532286065419750225452652610457932531801065478094283507991944278536471050177815
......
1800770781409200926729603012036399122612354223297965849193568220166221823827007473973626415778027283203257859436115043467834039248011308008970373580159115358623592785179693929237325906281417327707511367440182904304414404549092837187511274801071123317414291083508930334684914589548474523630602734787763752642650108051603681222208730507864063922554184820979550914053901623625867638329589057084622018536880047237486402357211985935911518591908559710461028858365500139708030451183599397419167324308926445889501688971003457521313556691540070097267225658102199913459475663435094075824268339011711162419371946058730204417615921460974678178193304750993733448069907261953901184615106218657480204867492382202923258637344388123757033376532121188827136
Prelude> Leaving GHCi.

real 0m1.060s
user 0m0.250s
sys 0m0.173s


And for more LOL's!

[ishpeck@slcatedjamu ~]$ time lynx -dump http://www.wolframalpha.com/input/?i=16384%5E16384
#[1]Wolfram|Alpha

* [2]Home
* [3]Examples
* [4]Products
* [5]Blog
* [6]About

*
+ [7]Wolfram Research
+
+ [8]Wolfram Mathematica
+ [9]Wolfram Demonstrations
+ [10]Wolfram MathWorld
+ [11]Wolfram Science
+ [12]WolframTones
+
+ [13]More

Experimental Feature

You have the Wolfram CDF Player installed and can now enable
Wolfram|Alpha Interactive to:
* Interact with your results using sliders and controls
* Rotate and zoom 3D graphics and visualizations
* Manipulate results directly in your browser

[14]Learn more [15]Remind me later

Experimental Feature


Thanks for helping us test Wolfram|Alpha with CDF!
Try these interactive examples:
* Interactively manipulate parameters
____________________ Submit
* Rotate 3D graphics
____________________ Submit
* Read plot values
____________________ Submit
* Animate dynamic processes
____________________ Submit
* Instantly build interactive interfaces
____________________ Submit


Experimental Feature


Thanks for helping us test Wolfram|Alpha with CDF!
Please tell us what you think:[16]Take a survey

Experimental Feature


[17]Learn more [18]Take a survey

[19]Wolfram|Alpha Computational Knowledge EngineEnter what you want to
calculate or know about:

____________________

Submit

[20]Examples[21]Random

To see full output on this page you need to enable JavaScript in your
browser. [22]More info
Computing
Computing...
__________________________________________________________________

Input:

16384^16384
[23]Save as image [24]Copyable plaintext [25]Mathematica form
__________________________________________________________________
__________________________________________________________________

Decimal approximation:

* [26]More digits

[27]1.13837518811535904250072068341232590877598871955010... 10^69049
__________________________________________________________________
__________________________________________________________________

Power of 10 representation:

10^(10^4.839157747319649)
__________________________________________________________________
__________________________________________________________________

Number length:

69050 decimal digits
__________________________________________________________________
__________________________________________________________________

Last few digits:

...1188827136
__________________________________________________________________

[28]Computed by Wolfram MathematicaDownload as: PDFLive Mathematica

... ...

real 0m1.025s
user 0m0.017s
sys 0m0.010s


Of course, this is all very far from scientific but it was amusing to try. I've noticed that clisp tends to out-perform Python on smaller numbers (I assume because Python's cache is helpind it out when there's a lot of repitition). Nobody who actually _tried_ to compute the desired value botched anything up (the way Python is wont to in some arithmetic situations).

I know Haskell tended to be much faster if you subtracted start-up time (which this test does not).

Wednesday, December 7, 2011

Wrote my first jquery plugin it strips out html for an input field

I needed a way to remove up html from my input from the users.  This is my first attempt at it.
(function ($) {
 
    $.fn.safeVal = function () {
        var value = $(this).val();
        var ret = $('<div>').html(value).text();
        return ret;
    };
})(jQuery);

Thursday, August 4, 2011

My Rules for Development

  1. If you think you need a region you really need a new class.
  2. If you are using a for loop in c# there is something wrong with your code.
  3. If you are using a foreach fix you code so you don't need it.
  4. If you think you want to use exceptions to control flow stop now and go to your room and think about what damage you may do.
  5. If you don't write a unit test it's not done.

Wednesday, May 18, 2011

Some Fun With Linq.

A friend of mine was asking me how I search through dictionary that contain lists of objects with Linq. After I chatted with him for a bit. I realized I don't do that.  I have one huge list that I parse out with linq.  It makes my life easier.  Here is a code example of what I would use.


        public class section
        {
            public string Group { getset; }
            public string Order { getset; }
            public string Section { getset; }
            public string Title { getset; }
        }
 
        static void Main(string[] args)
        {
            var sec = new List<section>();
            sec.Add(new section { Group = "1", Order = "1", Section = "1.1", Title = "one one" });           
            sec.Add(new section { Group = "1", Order = "3", Section = "1.3", Title = "one three" });
            sec.Add(new section { Group = "1", Order = "2", Section = "1.2", Title = "one two" });
            sec.Add(new section { Group = "2", Order = "1", Section = "2.1", Title = "two one" });
            sec.Add(new section { Group = "2", Order = "2", Section = "2.2", Title = "two two" });
            sec.Add(new section { Group = "3", Order = "1", Section = "3.1", Title = "three one" });
 
            //creates a diction with all the sections in order grouped by group.
            var jmp = sec.OrderBy(j => j.Order).GroupBy(c => c.Group).ToDictionary(c => c.Key, d => d.ToList());
            //gets one section form a section
            var wantedSection = sec.FirstOrDefault(c => c.Section == "2.2");  //return null if no iteem found
            //gets one section in the order you set in order
            var sectionOne = sec.Where(c => c.Group == "1").OrderBy(c => c.Order).ToList();                        
        }

Friday, April 22, 2011

Test Code that Doesn't

Consider the following code taken from an automated testing suite:


def group(self, group, options="", authUser=None, cmdOptions=""):
if options != "":
options = "-" + options

output, rCode = self._run(cmdOptions, "list {} group {}".format(options, group), authUser, returnOutput=True)
if rCode != 0 and output != None:
lines = output.splitlines()
if len(lines) > 1:
for line in lines:
if line.find("[debug]") == -1:
group = self._parseGroup(line)
else:
group = self._parseGroup(output)

return group, rCode

What's especially interesting about this piece of code is that if the program being called succeeds and returns multiple lines, only the very last one is considered the actual output. If the program being called by _run fails, the return value is the text of what you asked for!

Though this is part of an automated testing suite, no real checks take place. The only thing it bothers to do is ignore debugging output. But that's handy!

Friday, March 25, 2011

Chat between frinds

It's often the case where I learn more about programming from a conversation over google talk then I do form reading a book.  This is a copy of one such conversation between two of my friends.  I thought the content was good enough to actually post for others to read.


Sqrl says:
Feels nice to perfect a 468-line data model using LINQ extremely liberally

Llama says:
how does LINQ relate to a data model?

Sqrl says:
Probably the wrong word

There are a number of properties of my data model that I'm exposing that are little but fundamental interpretations of the data

That's where the LINQ resides

Llama says:
data operations then
technically speaking your data model should be POCO's

Sqrl says:
What's that?

Llama says:
Plain Old CLR Objects

Sqrl says:
Why?

Llama says:
ask yourself this question, what is a Data Model, simple answer, a unified representation of the data in a system
not a unified representatino of the logic in the system
by using POCO's you make your system firstly portable and simply definable

Sqrl says:
Well
I'm defining a system in which the rules can be changed dynamically by simply modifying some .csv or .xml files
For example, there is a number that defines how many slots you can put in your ship before the size in increased a level.
This size number is fundamental to the data itself, but emerges based on the rules
So, although it includes logic, I've included it in my data model
Defense and Speed are based on size and, again, fundamental
They also emerge from some logic

Llama says:
This is where i tell you, your system will never scale you've just written a very small idea
so if for example you want to do server side scaling of your game

Sqrl says:
Are you suggesting I should separate them into two different layers?

Llama says:
it won't happen and would be a nightmare
lol i'm suggesting you learn about software architecture
you can program, but the where and why needs to be taught

Sqrl says:
I try -_-

Llama says:
lol you suceed
dude
this is something i learned only 18 months ago at best

Sqrl says:
So would the problem be that so much computation is done server-side?

Llama says:
the problem is, if you try to do server side calculations you can simply push data easily in a POCO from client to server
your having to push the entire logic base with it and deploy the same logic on client and server
OR
do stateful server side objects which don't scale either

Sqrl says:
Well

Llama says:
meaning when you create an instance of an object it stays alive on the server, rather that data moving through a system

Sqrl says:
This particular data and rule set would be computed and immutable when the actual "game" part begins, I'll tell you that

Llama says:
having dicipline does NOT make up for architectural mistakes


Sqrl says:
hah
Fair enough
I'ma quote that, actually.

Llama says:
See your trying to apply a simple OOD which in truth is fundamentally flawed
by that, when you create an Object Oriented System, to be properly constructed it must implement this http://en.wikipedia.org/wiki/Solid_(object-oriented_design)
Its the only way of making an OO system scale and be properly designed

Sqrl says:
I never did understand where the line is drawn with SRP

Llama says:
more is better
meaning, if you have to break up logic into multiple logic blocks because it violates the single responsibility, then do so
so take this for example
you have a Repository object that handles CRUD (create, retrieve, update, delete) operations
now a repository pattern does not a happy llama make but its an easy way to explain this
Technically speaking the object can follow SRP if it does CRUD operations
but that can lead to a ton of operations right?

Sqrl says:
yeah

Llama says:
insert, update, delete, and data queries
so one could say that doing insert, update, delete, and select by id is one responsibility because its doing autonomous operations on an entity in the model
and any queries should be seperated out to a secondary or multiple objects in order to satisfy SRP
both are valid interpretations
however breaking it down further gives greater scope to the SRP making it more real

Sqrl says:
hrm
But certainly wouldn't create one object to generate the Defense, another to generate Speed

Llama says:
why not
they're components aren't they?
or is it making too many objects?

Sqrl says:
public int Speed
        {
            get
            {
                return (int)Math.Ceiling(this.AllSlots
                    .Where(i => i.SlotType == SlotType.Engine
                        || i.SlotType == SlotType.Universal)
                    .Where(i => i.SlottedSystem != null)
                    .Where(i => i.SlottedSystem is IShipEngine)
                    .Sum(i => (i.SlottedSystem as IShipEngine).Thrust)
                    / (float)this.Size);
            }
        }
That's it
Llama says:
ok, thats a horrible bastardization of a data layer
you did that in a getter? o.O

Sqrl says:
Hahahaha

Llama says:
dude, ICalculateSpeed ftw

Sqrl says:
Are you serious?

Llama says:
as a heart attack
you CAN use a factory to keep a singleton of it
but thats logic hiding in the data layer
its a calculation leading from one entity to a speed value
You do want to learn proper OO systems no?

Sqrl says:
Why would I use a singleton instead of a static method?

Llama says:
Its a piece of logic, which is encapsulated into an object
therfore keeping w/ the DIP principle you have an interface to define the operation, and an object instance to operate it
keeping a singleton just manages memory overhead
but you can manage that w/ the Factory
which yields flexibility
rather than a run of the mill rigidity that using a Utility class w/ a static method gives you
make sense?

Sqrl says:
Yeah
Damn good song btw http://listen.grooveshark.com/s/The+Truth+Of+A+Liar/2gag9R?src=5

Llama says:
i'll have to check it out on pandora

Sqrl says:
I can definitely see where the flexibility comes in
It builds more of an internal protocol-based system instead know-it-all master objects

Llama says:
see: God Object
suprisingly, it builds a stronger system with fantastic segregation
you can tune and tweak various parts of the system
AND
its bloody easy to unit test
you can create various proxy objects to plug into the system that mock actual logic, so your system can be 100% testable

Sqrl says:
And now

Llama says:
especially testing negatively

Sqrl says:
I have struggle with the decision of getting this thing done or plow through it so I can use it
It's a tool I wanted to use two weeks ago

Llama says:
Star Thugs?

Sqrl says:
yeah

Llama says:
hahaha
rebuild it yo
use it as a teaching moment for yourself

Sqrl says:
Well here's the good news
I'm still using MVVM, even though my models are a bit massive
So I can finish it off and refactor the models without remaining committed to my shit

Llama says:
sweet
well i got NUnit to start running my F# unit tests
namespace Llama.Test
open NUnit.Framework

[<TestFixture>]
type EndpointRegistryTests() =
    [<Test>]
    member x.add_value_to_registry() : unit =
        printfn "hello testing world 2"
        Assert.AreEqual(5, 5)
not bad for unit tests
Sqrl says:
Hahahaha

Llama says:
now i actually gotta fill in logic

Sqrl says:
Just testing the JIT
Iz coo

Llama says:
next is start testing components in my node server

Sqrl says:
How portable is the ViewModel architecture to ASP MVC?

Llama says:
depends on what you do
if its my framework Kronos
extremely
we actually had this type of layer for how data moves through layers

ViewModel -> Domain
View -> Controller -> Provider -> (Service : Optional) -> NHibernate
the domain object would live till the controller
then we'd do a transform using AutoMapper to a ViewModel to be used in the View
we use this for a very damn good reason, Domain objects are actually dynamically generated inherited objects that do lazy loading etc that are attached to a Session
So if we access a collection on an object in a view, we're literally running a db query in the view layer

Sqrl says:
lololol

Llama says:
So thats why we use ViewModels
So you know, Crystal thought my description of your getter as being a grose bastardization was rude
She says i should be nicer
>,>

Sqrl says:
Hahahaha

Llama says:
Granted, i won't be, because we devs are the way we are

Sqrl says:
'course

Llama says:
but its the thought that really counts
i told her it def wasn't the worst thing i've ever said

Sqrl says:
Gawd, what do you do when ignorant people call cute flash animations "programming"?

Llama says:
cuz they think it is

Wednesday, March 2, 2011

The way of Testivus

A friend of mine linked me to TheWayOfTestivus.pdf the other day.  It is a funny read that talks about unit testing and has a very pragmatic view on it.  Read it enjoy it and apply it. I think you will find that it improves your development process if you do.

Tuesday, March 1, 2011

CodeProject has some gems in it.

I friend linked me to this the other day and it changed how I program.  It's not very often that one article changes the way I handle coding but this allowed me to clean up a lot of code.  From the work in the article I have added one more function as well.


public static TResult Let(this TInput o, Func evaluator, TResult failValue)
            where TResult : class
            where TInput : class
        {
            if (o == nullreturn failValue;
 
            return evaluator(o);
 
        }
This one allows for the calling of functions that return a value.

Wednesday, February 16, 2011

Date Time you are doing it wrong again.

The other day I reading the greatest developer fallacy or the wisest words you'll ever hear and then today I found some code that I think illustrated his point that learning it when you need it isn't always the way to go. This code looks very much that way.  Although I think a quick Google search would have found better code then this even if you didn't know what words to look for.


System.Text.StringBuilder mxIsDt = new System.Text.StringBuilder();
mxIsDt.Append(DateTime.Now.Year.ToString());
mxIsDt.Append(DateTime.Now.Month.ToString());
mxIsDt.Append(DateTime.Now.Day.ToString());
mxIsDt.Append(DateTime.Now.Hour.ToString());
mxIsDt.Append(DateTime.Now.Minute.ToString());
mxIsDt.Append(DateTime.Now.Second.ToString());
string mxDate = mxIsDt.ToString();
Which converts into around 70 lines of IL and takes just 19160 milliseconds to complete.   Now my question is why wouldn't you use ToString on DateTime to do this. 

var d = DateTime.Now.ToString("yyyyMdhms");            
Which takes 8 lines or less in IL and takes 1213 milliseconds to complete. It's way less code easier to maintain and examples on how to do this can be found all over the web.