programming is hard http://programmingishard.com/ making programming easier one snippet at a time en-us Fri, 26 Sep 2008 02:36:17 +0000 Fri, 26 Sep 2008 02:36:17 +0000 http://blogs.law.harvard.edu/tech/rss chad@spicycode.com Skew effects http://programmingishard.com/code/527 // class clases.utilities.SkewFX { // Funcion para hacer el efecto de skew a movieclips // public static function goSkew (mc : MovieClip, xSkew : Number, ySkew : Number, setHR : Boolean) : Void { var rad : Number = (Math.PI / 180); var trans : Object = new flash.geom.Transform (mc); var matrix : Object = trans.matrix; matrix.a = isNaN (ySkew * rad) ? matrix.a : Math.cos (ySkew * rad); matrix.b = isNaN (ySkew * rad) ? matrix.b : Math.sin (ySkew * rad); matrix.c = isNaN (xSkew * rad) ? matrix.c : Math.sin (xSkew * rad); matrix.d = isNaN (xSkew * rad) ? matrix.d : Math.cos (xSkew * rad); trans.matrix = matrix; // if (setHR) { var loaderRef : Object = mc; mc.onEnterFrame = function () { var pixelData : flash.display.BitmapData = new flash.display.BitmapData (mc._width, mc._height); pixelData.draw (mc); loaderRef.removeMovieClip (); loaderRef.attachBitmap (pixelData, 1, true, true); this.onEnterFrame = null; } } } } Thu, 25 Sep 2008 22:36:15 -0400 Main class http://programmingishard.com/code/526 // class clases.Main { public static var mcMain : MovieClip = new MovieClip (); // // // Constructor que activa la clase // public function Main (mainMC : MovieClip) { mcMain = mainMC; } // // // Capturar el XML de los productos // public function getXML () : Void { } } Thu, 25 Sep 2008 22:34:24 -0400 A better field error proc http://programmingishard.com/code/525 # this applies a css class of field_with_error to the label/select/textarea/input tags, no wrapping containers ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| msg = instance.error_message error_style = "field_with_error" if html_tag =~ /<(label|input|textarea|select)[^>]+class=/ class_attribute = html_tag =~ /class=['"]/ html_tag.insert(class_attribute + error_style.size.next, " #{error_style} ") elsif html_tag =~ /<(label|input|textarea|select)/ first_whitespace = html_tag =~ /\s/ html_tag[first_whitespace] = " class='#{error_style}' " end html_tag end Thu, 18 Sep 2008 16:25:44 -0400 Random Elements http://programmingishard.com/code/524 class Array # returns a random element of the array def rand self[Kernel.rand(length)] end end class Hash # returns a random key-value pair def rand temp_key = self.keys.rand [temp_key, self[temp_key]] end end module Kernel # random_n_digit_number(1) returns a number between 1 and 9 inclusive # random_n_digit_number(3) returns a number between 100 and 999 inclusive def random_n_digit_number(n) raise ArgumentError, "expected digit length to be greater or equal to 1, received #{n.inspect}" if !n.is_a?(Numeric) || n < 1 return rand(10) if n == 1 min = 10**(n-1) max = (10**n)-1 rand(max-min+1) + min end end class Range # (1..10).rand returns a number between 1 and 10 inclusive # (1...10).rand returns a number between 1 and 9 inclusive # (2..2).rand returns 2 # (2...2).rand is equivalent to 2 + Kernel.rand() # (Date.parse('2008-08-01')..Date.parse('2008-08-31')).rand returns a date between the first and last dates inclusive # (Time.now..(Time.now+60)).rand returns a time between the first and last times inclusive def rand self.first + Kernel.rand(self.last - self.first + (self.exclude_end? ? 0 : 1)) end end Tue, 19 Aug 2008 18:05:19 -0400 Create a Hash from an Array object http://programmingishard.com/code/523 >> a = [1,2,3,4,5,6,7,8,9,10] => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >> Hash[ *a ] => {5=>6, 1=>2, 7=>8, 3=>4, 9=>10} >> ?> b = [ [1,2], [3,4], 5, 6, 7, 8, 9, 10 ] => [[1, 2], [3, 4], 5, 6, 7, 8, 9, 10] >> Hash[ *b ] => {5=>6, [1, 2]=>[3, 4], 7=>8, 9=>10} Tue, 19 Aug 2008 17:56:32 -0400 getDistance http://programmingishard.com/code/522 private function getDist(x1:Number, y1:Number, x2:Number, y2:Number):Number { var dx:Number = x2 - x1; var dy:Number = y2 - y1; return Math.sqrt(dx*dx + dy*dy); } Wed, 06 Aug 2008 13:43:33 -0400 title http://programmingishard.com/code/521 posting undeletable apparently Wed, 30 Jul 2008 05:18:56 -0400 Div to fill remaining space on page (IE, quirks-mode only) http://programmingishard.com/code/520 &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> &lt;head> &lt;title>Ehr&lt;/title> &lt;style type="text/css" media="screen" id="test"> html, body {height: 100%;} #masthead { height: 90px; position: absolute; width: 100%; } #navbar { height: 30px; padding: 4px; position: absolute; left: 0px; bottom: 0px; width: 100%; } #content { height: 100%; padding-top: 93px; } &lt;/style> &lt;/head> &lt;body style="margin:0px;padding:0px;"> &lt;div id="masthead"> MASTHEAD <i>(fixed size, absolute positioned to top)</i> &lt;div id="navbar">NAV (<i>nested inside masthead</i>)&lt;/div> &lt;/div> &lt;div id="content"> CONTENT <i>(standard document positioned, with padding-top of masthead height)</i> &lt;/div> &lt;/body> &lt;/html> Wed, 30 Jul 2008 05:03:34 -0400 Confusication http://programmingishard.com/code/519 # Summoned into existence by my co-worker Ehren def confusicate_class(klass) methods = {} (klass.instance_methods - Object.instance_methods).each do |meth| methods[meth] = klass.instance_method(meth.to_sym) end klass.class_eval do methods.keys.each do |meth_name| define_method(meth_name) do current = methods.keys[rand(methods.keys.size)] meth = methods[current] methods.delete(current) meth.bind(self).call end end end end class Foo def one; 1; end def two; 2; end def three; 3; end end confusicate_class(Foo) f = Foo.new %w{one two three}.each do |n| puts "#{n} => #{f.send(n)}" end # OUTPUT # ~/$ ruby r.rb # one => 3 # two => 1 # three => 2 # ~/$ ruby r.rb # one => 3 # two => 2 # three => 1 # ~/$ ruby r.rb # one => 2 # two => 1 # three => 3 Tue, 08 Jul 2008 16:18:16 -0400 Explicitly naming a partials local collection variable name http://programmingishard.com/code/518 # From the little-but-useful department comes a new addition to Rails that lets you explicitly name the local # variable exposed to a partial template when using a collection partial. So, for instance, in this statement: render :partial => 'employees', :collection => @workers, :as => :person # each element of the workers collection will be exposed as person within the employees template. # No longer are you hostage to your template name. Mon, 07 Jul 2008 07:56:49 -0400 Enabling wrap in pre tags http://programmingishard.com/code/517 pre { white-space: pre-wrap; /* css-3 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ } Sun, 06 Jul 2008 10:59:34 -0400 An example of accurate math in PHP http://programmingishard.com/code/516 // PHP Gregorian date calculation algorithm based on work by Gary Katch // http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html // http://alcor.concordia.ca/~gpkatch/gdate-c.html function dayfromdate($year,$month,$day){ // define as floats $m = 0.0; $y = 0.0; #$m = ($month + 9) % 12; #$y = $year - $m/10; $m = bcmod(bcadd($month,9),12); $y = bcsub($year,(bcdiv($m,10))); # Gregorian calendar takes the length of a year to be 365.2425 days: # 365.0000 + 0.2500 - 0.0100 + 0.0025 # or # 365 + 1/4 - 1/100 + 1/400 using integers # made into a discrete function this is # d = 365y + int(y/4) - int(y/100) + int(y/400) // define as floats $toreturn = 0.0; #$toreturn = $y*365 + $y/4 - $y/100 + $y/400 + $monthoffset +$dayoffset $toreturn = bcmul($y,365); $toreturn = bcadd($toreturn,bcdiv($y,4)); $toreturn = bcsub($toreturn,bcdiv($y,100)); $toreturn = bcadd($toreturn,bcdiv($y,400)); # month offset # length of months are not the same, feb is not fixed # so we start the calendar year with March # this makes leap days always added on to the end of the year # and do not change day offsets for the beginning of the months #$monthoffset = ($month*306 + 5) / 10; $monthoffset = 0.0; $monthoffset = bcdiv(bcadd(bcmul($m,306),5),10); $toreturn = bcadd($toreturn,$monthoffset); # day offset, start at zero #$dayoffset = $day - 1; $dayoffset = 0.0; $dayoffset = bcsub($day,1); $toreturn = bcadd($toreturn,$dayoffset); return $toreturn; } function datediff($d1,$d2){ // this is the main function. // takes two dates of the format YYYY-MM-DD // and displays the difference in days between the two // by calling 'dayfromdate', which does all the math $date1 = split('-',$d1); $date2 = split('-',$d2); $year1 = $date1[0]; $month1 = $date1[1]; $day1 = $date1[2]; $year2 = $date2[0]; $month2 = $date2[1]; $day2 = $date2[2]; $res = 0.0; $res = bcsub(dayfromdate($year1,$month1,$day1),dayfromdate($year2,$month2,$day2)); $result = (string)$res; return "$d2 is $result days after $d1<br/>\n"; } function gendate(){ // generate a random gregorian date.. for testing $year = rand(1600,3000); $month = rand(1,12); $day = rand(1,29); if($month < 10){ $tm = "0".$month; }else{ $tm = "".$month; } if($day < 10){ $td = "0".$day; }else{ $td = "".$day; } $d1 = "$year-$tm-$td"; $d2 = array('y' => $year, 'm' => $month,'d' => $day); return array('text-date' => $d1,'num-date' => $d2); } // unit test code - shows it works for arbitary Gregorian dates.. // run it from the command line to test against mysql5's datediff version for($i<0;$i<10;$i++){ $d1 = gendate(); $d2 = gendate(); $dd = datediff($d1['text-date'],$d2['text-date']); echo "[Datediff]" . $dd; # change below to match your local mysql5 test account! :) $con = mysql_connect('localhost','seo','seo'); sleep(1); $res = mysql_query("SELECT DATEDIFF('".$d1['text-date']."','".$d2['text-date']."') as days") or die(mysql_error()); $row = mysql_fetch_array($res); echo "[MySQL] Mysql reports actual difference is = " . $row['days'] ."<br/>\n"; if(!bccomp($row['days'],$dd)){ echo "Doesn't add up.."; break; } echo "--\n"; mysql_close($con); } // here is an example test run, showing it is working: #[Datediff]1710-09-02 is 455209 days after 2956-12-27<br/> #[MySQL] Mysql reports actual difference is = 455209<br/> #-- #[Datediff]2905-02-25 is -466866 days after 1626-12-01<br/> #[MySQL] Mysql reports actual difference is = -466866<br/> #-- #[Datediff]1605-10-23 is 113856 days after 1917-07-16<br/> #[MySQL] Mysql reports actual difference is = 113856<br/> #-- #[Datediff]2401-08-20 is 34469 days after 2496-01-03<br/> #[MySQL] Mysql reports actual difference is = 34469<br/> #-- #[Datediff]1863-09-16 is 16705 days after 1909-06-12<br/> #[MySQL] Mysql reports actual difference is = 16705<br/> #-- #[Datediff]2631-09-06 is 42712 days after 2748-08-15<br/> #[MySQL] Mysql reports actual difference is = 42712<br/> #-- #[Datediff]2714-08-09 is -12026 days after 2681-09-04<br/> #[MySQL] Mysql reports actual difference is = -12026<br/> #-- #[Datediff]1844-11-19 is 229379 days after 2472-11-25<br/> #[MySQL] Mysql reports actual difference is = 229379<br/> #-- #[Datediff]1640-02-11 is 464018 days after 2910-07-21<br/> #[MySQL] Mysql reports actual difference is = 464018<br/> #-- #[Datediff]1779-07-15 is 300513 days after 2602-04-25<br/> #[MySQL] Mysql reports actual difference is = 300513<br/> #-- Fri, 04 Jul 2008 09:09:54 -0400 Computer: Where am I right now in my rails application? http://programmingishard.com/code/515 # This came from 20 minutes of goofing off before_filter :where_am_i_right_now def where_am_i_right_now %x{say 'processing #{params[:action].humanize}, on the #{params[:controller]} controller'} end Thu, 26 Jun 2008 15:12:34 -0400 Create a Hash from two Array objects http://programmingishard.com/code/514 # Requires Ruby 1.8.7 or higher. >> keys = [1,2,[3,4]] => [1, 2, [3, 4]] >> values = ['a','b',['c','d']] => ["a", "b", ["c", "d"]] >> Hash[ * keys.zip(values).flatten(1) ] => {1=>;"a", [3, 4]=>["c", "d"], 2=>"b"} Sun, 22 Jun 2008 16:48:55 -0400 Simple FOR Loop http://programmingishard.com/code/513 var hour; var ampm; for (hour=1; hour<24; hour++) { if (hour < 12) {ampm="am"} if (hour >= 12) {amppm="pm"} if (hour < 13) { document.write(hour + ampm) } else { document.write((hour-12) + ampm) } document.write("<br>"); } Sun, 22 Jun 2008 10:52:23 -0400 Create a Date object from a Date inspect http://programmingishard.com/code/512 # Seeing things like "&lt;Date: 4909275/2,0,2299161&gt;" in logs gives no immediate # clue what that date is. Now one can use Date.new_from_inspect to see what date the # inspect string represents. >> Date.new_from_inspect('#&lt;Date: 4909275/2,0,2299161&gt;').to_s => "2008-06-20" >> Date.new_from_inspect(Date.today.inspect) == Date.today => true class Date def self.new_from_inspect(date_inspect_string) args = date_inspect_string.split(/[^\d]/).reject{|s| s.empty?}.map{|s| s.to_i} new!( Rational(*args.first(2)), *args.last(2) ) end end Fri, 20 Jun 2008 16:16:51 -0400 A nice simple jquery logger http://programmingishard.com/code/511 jQuery.fn.log = function (msg) { console.log("%s: %o", msg, this); return this; }; Tue, 17 Jun 2008 09:00:52 -0400 Please install my gem post haste good sir! http://programmingishard.com/code/510 # To install most quickly instead of updating the source cache do gem install rmagick --no-update-sources Fri, 13 Jun 2008 09:08:37 -0400 Manpage fix for programs installed via MacPorts on OSX http://programmingishard.com/code/509 export MANPATH=/opt/local/share/man:$MANPATH Thu, 12 Jun 2008 15:23:19 -0400 Never do this please http://programmingishard.com/code/508 # Stick this in a model, and enjoy. Or don't. Actually don't. This was # written as a crazy experiment all about coulda, not about shoulda. class ActiveRecord::Base def current_user ObjectSpace.each_object(ApplicationController) do |found_obj| return found_obj.send!(:current_user) if found_obj.respond_to?(:current_user) end end end Thu, 12 Jun 2008 10:58:15 -0400