Technology Musings

August 05, 2012

Snippets / Simple Sage Plots for Teaching Functions

JB

I'm teaching calculus to some homeschool students this year, and I wanted to have a bunch of function plots printed out to show them.  Therefore, I turned to Sage, which I have never used.  It is great!  You have to know a few other math software pieces to really understand it, but it's not that bad.  Someone needs to do a general "how to use sage", and some day I might.

Anyway, here's my quick function for plotting graphs for students that some of you might like.

In one of the evaluation boxes, type the following:

def simpleplot(f, range=(-5,5,-5,5)):
p = plot(f, (x, range[0], range[1]))
p += text("$" + latex(f) + "$", (0, range[2] - (range[3] - range[2]) * 0.1), fontsize=30, rgbcolor=(1,0,0))
p.axes_range(range[0], range[1], range[2], range[3])
show(p, figsize=12)

What this does is create a function called "simpleplot" which will do the following:

  • Plot the given function on a default domain of -5, 5
  • Typeset the function using LaTeX, and insert the function slightly below the graph (I calculated it at 10% of the graph size).  It prints in red at 30 point size.
  • Set the axes to be -5, 5, -5, 5 (I used uniform axes on all the functions so they can compare the differences between graphs easier)
  • Draw the whole thing at 3x the normal size (figsize=12 - default is 4).

Now, I can just do:

simpleplot(1/x)

And it gives me my output!

July 23, 2012

Snippets / DVD Rescue! Getting files off of an unfinalized DVD

JB

Just wanted to shout out and say thanks to Flay for saving me!  I had a DVD that I forgot to finalize, but Flay had a nice set of instructions for how to manually copy off the files from the DVD drive.

Now I can finish editing and posting the videos for the Engineering and Metaphysics conference.

June 26, 2011

Snippets / Misc stuff I found out

JB

Objective-C PostgreSQL stuff:


Misc:
Building a shared library on OSX: (see here):
gcc -dynamiclib -install_name /usr/local/lib/libfoo.2.dylib  -compatibility_version 2.4 -current_version 2.4.5 -o libfoo.2.4.5.dylib source.o code.o

I have also seen the options -undefined suppress -flat_namespace here

Another dylib link

Caution mixing shared and archive libs

Seth Godin - how to run a useless conference

 

June 10, 2010

Snippets / Cross-browser DIV Rotation by arbitrary degrees in CSS and/or javascript

JB

I've spent most of the day on this, so I thought I would share.  Most people don't know this, but CSS3 has some *really* cool stuff coming - auto-rounded corners, gradients, and.... DIV rotations!  Unfortunately, it will be about 5 years before any of this becomes mainstream.  IE8 only has the very beginnings of CSS3 support.

So is there any way to get this on current browsers?  Yes!  The fine folks at CSS3Please.com have given us a way to do some of these cool effects using existing CSS.  If you just want, just go their, edit the stylesheet on the web page (yes! it is editable!), and copy/paste the resulting CSS into your CSS file.

But what if you want dynamic rotation?  Well, I looked at the CSS3Please source code, and figured out how it was all being calculated.  The IE6, IE7, and IE8 part is the worst, because it relies on a DirectX Matrix transform operation (isn't Internet Explorer always fun to work with?).  Not superfun, but do-able.  However, to get this calculated, we will need a Matrix library.  So, first, download and install the sylvester javascript library.  Then, put this javascript into your page:

<script src="sylvester.js"></script>
<script type="text/javascript">
function degreesToRadians(num) {
	return (num) * Math.PI / 180;
}
function createIEMatrixString(M) {
	return 'M11=' + M.e(1, 1) + ', M12=' + M.e(1,2) + ', M21=' + M.e(2,1) + ', M22=' + M.e(2,2);
}
function rotateElement(e, deg) {
	deg_str = deg + "";
	rotate_transform = "rotate(" + deg + "deg)";
	matrix_str = createIEMatrixString(Matrix.Rotation(degreesToRadians(deg)));
	filter_str = "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', " + matrix_str + ")";

	e.style["rotation"] = deg_str + "deg"; // CSS3
	e.style.MozTransform = rotate_transform; // Moz
	e.style.OTransform = rotate_transform; // Opera
	e.style.WebkitTransform = rotate_transform; // Webkit/Safari/Chrome
	e.style.filter = filter_str; // IE 6/7
	e.style.MsFilter = filter_str; // IE 8
	e.style["zoom"] = "1"; // ??? Probably IEs
}
</script>

Now, you can just do:

rotateElement(document.getElementById("whatever"), 20);

And that will rotate the element.  Note that this *sets* the rotation, so if I do this several times it will only keep the rotation at what I set it to, it won't keep on adding rotations.

Anyway, a little bit of work, a little bit of code for your client to download, but it works.

UPDATE - just found this jquery plugin that *might* do something similar, but haven't looked at it closely yet.

May 26, 2010

Snippets / A Simple HTML Geolocation Map with Twitter and Google Maps

JB

New Medio just released <a href="http://www.newmedio.com/site/postings/17?section_id=2">a cool new tool to do geolocation/geotagging maps of Twitter posts</a>.  Can be used HTML-only (no Javascript coding required!) or with a Rails plugin. 

June 26, 2009

Snippets / What's Taking So Long?

JB

There are a lot of performance analysis tools for Rails logs.  However, sometimes you just need something quick and dirty.  This one helped me out.  1-line perl script to show all Rails log lines which took more that 100milliseconds to produce:

perl -n -e 'print if(m/\((\d+\.\d+)ms\)/ && $1 > 100);' log/development.log

UPDATE - Here's another handy one:

 tail -20000 log/production.log|grep 'Completed in'|cut -d" " -f3,11|sort -n

December 18, 2008

Snippets / Docx and Open Packaging Conventions for Ruby and Rails

JB

I just finished the first iteration of my Ruby on Rails plugin for handling Microsoft's new Open Packaging Conventions file format, which is their new container format for XML-based file formats in Microsoft Office.  DOCX, Microsoft's new XML-based format for Word is probably the most widely used of these. 

Open Packaging Conventions is basically a zipfile containing one or more components, and those components' relationship to each other is defined by other files within the zipfile.

To add rubyopc to your Rails app, do:

script/plugin install http://rubyopc.googlecode.com/svn/trunk/rubyopc

Here is how you would make a DOCX file with it:

OpenPackagingConventions::Package.with_package("test.docx") do |p|
p.add_part("/word/document.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", <<EOF)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<w:body>
<w:p w:rsidR="00EA68DC" w:rsidRPr="00C703AC" w:rsidRDefault="00EA68DC" w:rsidP="00EA68DC">
<w:pPr>
<w:rPr>
<w:lang w:val="es-ES_tradnl"/>
</w:rPr>
</w:pPr>
<w:r>
<w:t>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc at risus vel erat tempus posuere. Aenean non ante. Suspendisse vehicula dolor sit amet odio. Sed at sem. Nunc fringilla. Etiam ut diam. Nunc diam neque, adipiscing sed, ultrices a, pulvinar vitae, mauris. Suspendisse at elit vitae quam volutpat dapibus. Phasellus consequat magna in tellus. Mauris mauris dolor, dapibus sed, commodo et, pharetra eget, diam.
</w:t>
</w:r>
<w:r w:rsidRPr="00C703AC">
<w:rPr>
<w:lang w:val="es-ES_tradnl"/>
</w:rPr>
<w:t>
 Nullam consequat lacus vitae mi. Sed tortor risus, posuere sed, condimentum pellentesque, pharetra eu, nisl.
</w:t>
 </w:r>
</w:p>
</w:body>
</w:document>
EOF

p.add_part_to("/word/document.xml", "/word/styles.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", <<EOF)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:styles xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:style w:type="paragraph" w:styleId="Normal">
<w:name w:val="Normal" />
<w:rPr>
<w:b />
</w:rPr>
 </w:style>
</w:styles>
EOF

This will create a small word document called "test.docx".

You can find the official documentation for these file formats here.

 

August 25, 2008

Snippets / Rails Sorting

JB

I always have trouble formulating exactly how sorts should work on Rails controllers that are called from sortable_element.  Therefore, I created the following method for ApplicationController which helps out a lot:

  def sort_assoc_members(assoc, ary, position_method = :position)
ary.each_index do |ary_idx|
assoc.find(ary[ary_idx]).update_attributes(position_method => (ary_idx + 1))
end    
end

Then, to use it, just create a sort action like this:

def reorder
sort_assoc_members(WhateverItem, params[:whatever_list])
end

This makes life much easier.

August 13, 2008

Snippets / TinyMCE + Prototype AJAX + RAILS

JB

NOTE - I have no idea why the formatting here is all messed up. It should be usable anyway since the snippets are fairly small

Using TinyMCE from Ruby on Rails is sometimes a bit tricky.  We tend to assume that all HTML components work the same - they can be added and removed at will.  However, TinyMCE components have to be explicitly added and removed - and as such they can be really painful.

In addition, TinyMCE components have to be saved back to the form in order to be serialized by Prototype (which is used by Rails for remote forms - remote_form_for, link_to_remote, etc.).

Therefore, I came up with the following, which doesn't completely remove the pain, but it at least eases it somewhat.  First of all, it modifies the Prototype library slightly to trigger a tinyMCE.triggerSave(true, true) every time a form is serialized (i.e. for remote forms and links).  Now you don't have to remember to do that anymore! Next, it provides a simple RJS helper to unregister/reregister TinyMCE editors when doing Ajax page manipulation in Rails.

Anyway, here are the steps:

Step 1

Put the following code into application.js:

//Register all TinyMCE instances on the page
function register_all_tiny_mce_editors() {
tinyMCE.init({
mode : "textareas",
theme : "advanced",
editor_selector : "editor"
});    
//NOTE - if you have other registration functions, put them here, too.
}
//Unregister all TinyMCE instances on the page
function unregister_all_tiny_mce_editors() {
tinyMCE.triggerSave(true, true);
for(editor_id in tinyMCE.editors) {
editor_elem = $(editor_id);
if(editor_elem) {
editor = tinyMCE.editors[editor_id];
tinyMCE.remove(editor)
}
}
} 
//Convince Prototype to do a TriggerSave anytime it is doing form serialization
var original_form_serialize_elements = Form.serializeElements;
Form.serializeElements = function(elements, gethash) {
try {
//Copy TinyMCE values back onto the regular form elements
tinyMCE.triggerSave(true, true);                
} catch(err) {
//Don't do anything - just means TinyMCE isn't loaded
}
return original_form_serialize_elements(elements, gethash);
}

Step 2

Put the following code into your layout:

<%# Modify this to wherever you put TinyMCE %>
<%= javascript_include_tag "tiny_mce/tiny_mce.js" %>
<script type="text/javascript">
tinyMCE.init({
mode : "textareas",
theme : "advanced",
editor_selector : "editor"
});
<%# Add/modify the init statement to include any other options you want  %>
<%# Be sure to use the same code as you used above in the register_all_tiny_mce_editors() function %>
</script>
<%# PUT ALL OTHER JAVASCRIPT INCLUDES ___AFTER___ THIS ONE OR ELSE TINYMCE COULD BREAK!! %>

Step 3

Now, put the following in application_helper.rb:

  def tmce_update(page, &block)
page << "unregister_all_tiny_mce_editors();"
yield
page << "register_all_tiny_mce_editors();"
end

Step 4

Now, in all RJS files which could cause TinyMCE textareas to appear/disappear, you can do the following:

tmce_update(page) do
#Perform RJS operations which affect TinyMCE areas here 
end

And now all TinyMCE areas will start behaving for you!  Note that this ONLY works with RJS-based Ajax calls - it doesn't work if you use the :update parameter, but you shouldn't be using that anyway.  Always do Ajax updates with RJS!

July 07, 2008

Snippets / Scoped has_many :through

JB

In Rails, has_many :through is an excellent way to do join tables.  For example, I can have a person, a project, and a person_project to define the people I have assigned on projects.  This would be setup as follows:

class Person < ActiveRecord::Base
has_many :person_projects
has_many :projects, :through => :person_projects
end 
class Project < ActiveRecord::Base
has_many :person_projects
has_many :people, :through => :person_projects
end
class PersonProject
belongs_to :person
belongs_to :project
end

So, if I have a Project object called proj, I can do proj.people and get access to all the people on the project. I can also use it as a straight arra, and push individual Person objects onto proj.people, and the appropriate records in PersonProject will be created.

However, let's say that we add an additional value to PersonProject called "role".  Let's say this can be set to 'ADMIN', 'DESIGN', or 'TECH'.   Now pushing onto the proj.people array doesn't help much, because it doesn't fill out the role.  I created a snippet of code inspired by Josh Susser's solution, but which I think works a little better.  With this new code, I can rewrite the Project class (and the Person class, if I wanted) like this:

class Project < ActiveRecord::Base
has_many :person_projects
has_many :people, :through => :person_projects
scoped_has_many_through :admins, :through => :person_projects, :source => :person, :scope => { :role => "ADMIN" }
scoped_has_many_through :techs, :through => :person_projects, :source => :person, :scope => { :role => "TECH" }
scoped_has_many_through :designs, :through => :person_projects, :source => :person, :scope => { :role => "DESIGN" }
end

So the code to do that is as follows, although there's probably a more Rails-ish way to do this:

module ActiveRecord
class Base
def self.scoped_has_many_through(assoc, opts)
has_many_scope = opts.delete(:scope)
conditions_scope = Hash[*has_many_scope.to_a.map{|ent|
["#{opts[:through].to_s.pluralize}.#{ent[0]}", ent[1]]
}.flatten]
opts[:conditions] ||= {}      
if opts[:conditions].is_a?(Hash)
opts[:conditions] = opts[:conditions].merge(conditions_scope)
else
raise "Conditions must be a hash for conditions_scope!"
end
has_many assoc, opts do        
#Using define_method instead of def in order to make it lexically scoped
define_method(:construct_owner_attributes) do |reflection|
atts = super(reflection)
return atts.merge(has_many_scope)
end
end
end
end
end 

I have a few things like this.  I might package them together into a plugin sometime.  On the one hand, code snippets this small seem silly for a plugin.  On the other hand, plugins make it easily reusable, and perhaps I could batch several of them together, even if they aren't related.