PullMonkey Blog


18 Jan

Ruby PDF Reader Gem Tutorial


I've been doing a lot of work these days dealing with PDFs and for the most part I've been happy with using poppler-utils' pdftohtml. And that is great if you don't care about positioning or formatting and just care about the content. But for those of you who, like me, have run across the need to know text positioning, font size, indentation, coloring, etc., then we will have to use something more.

I had given just about every other option a chance before I finally found the pdf reader gem. But when I found pdf reader, it didn't have much documentation and it wasn't entirely clear how to get started using it and if it would work. Well, I can tell you that it will work and after playing with the examples a lot of it became much clearer. I learned a lot that would probably be useful for a few other people out there, hence this post.
Ok, well to get started, take a look at the github repository for pdf reader. You don't need to spend too much time, but just note a few places like the examples directory and the list of callbacks.

You should probably familiarize yourself with this PDF specification too - found here. It really came in handly when trying to figure out what arguments are being passed around what they represent.

Let's get started -

Step 1:  Install the gem

Yah, this is a pretty easy step, but it is required :)
sudo gem install pdf-reader

Step 2:  Find a PDF (or PDFs) to use

It would be best to have several PDFs for you to work with since the callbacks could vary depending on the PDF.
NOTE: For these examples, I'm using a really simple PDF, pdf reader could take a while on some PDFs and seem as though it is hanging but it is not, it is just chugging away right around line 283 of this file, reading each byte of your PDF.

Step 3: List the possible callbacks and their args for one of your PDFs

The point of this is to find out what methods we can write for pdf reader to call when it encounters the various parts of our PDF.
The BIG One that you will most likely use is show_text() or some form of it like show_text_with_positioning().
But, for now, THIS all depends on the PDF file you are using, so we need to find out what your PDF uses and go from there.

The easiest way to do this is to follow this example and just substitute "somefile.pdf" with the path to your pdf file.

Run it and you will see a long list of possible callbacks and their arguments. It is likely all squished together, so you can simply change the line of your code that says

puts cb

to

puts cb.inspect

and get a MUCH better look at everything.

We will start with show_text, so

grep

for show_text and see what you get. For my PDF, I have mostly show_text_with_positioning.

Step 4: Do some lookups

What are the args they are showing me for my callbacks and how do we find out?
You can do this two ways, try your luck at searching the pdf file for "show text" or "show text with positioning" and see what you get. Or you can lookup the token used to represent show_text or show_text_with_positioning.
The first way is pretty obvious, so on to the second - look in the list of callbacks I had your familiarize yourself with earlier, starting on line 172. Looking through we can find show_text and show_text_with_positioning, having Tj and TJ as their operators. Alright, now we have something to look up - "TJ". Well, I found it on page 251 of the PDF Specification from earlier. Some of descriptions for the operators will require rereading but you will get the hang of it.

Step 5: Use what we found

Now that we know how the show_text_with_positioning works and what args it brings in, we can write our code.
We need an instance of a receiver to pass to the PDF Reader. This is just a class that has methods likes show_text() of show_text_with_positioning(). Our receiver could look something like this:

Now we just need to create our receiver instance an pass our PDF file to pdf reader:

Don't forget to require the pdf reader at the top of your script like this:

require 'rubygems'
require 'pdf/reader'

Step 6: Check out the results

If we run our script, we will see all the text that uses Tj or TJ print out.

This is just the beginning and you can pick and choose any of the callbacks from that list (list of operators) and implement just about anything.

At the beginning of this post, I mentioned that I was concerned about positioning. This means I had to get very familiar with the text matrix operator (Tm), found on page 250 of the specification. It takes six arguments (a-f) all representing one thing or another and it is not very well documented. From what I can gather, the first four (a through d) are for things like scale and rotation, the last two e and f are for position on the page, where e is along the x axis and f along the y axis.

There is another text positioning operator that I saw quite often and that is move_text_position (Td operator, page 249 of the specification) that actually provides the x and y (unscaled) text space units coordinates. So if y is -1, that just means go to the next line and if y is 0, stay on the same line, -2, move down two lines, 2, move up two lines, etc. x is for indentation or horizontal spacing and represents the number of characters (spaces) to offset the text position by.

I hope this helps and a huge thanks goes to James Healy for his grand work on pdf reader.


06 Jan

POST OFC Graph as Image


I was asked recently (well sort of) to give an example of saving an image to the server. If you look at teethgrinder's example for this, you will see that he has made available an external interface to do just that - POST your graph as png raw data to your server for storage. This has many benefits such as saving the image for use in a PDF report or for printing, since we know at times it is a bit troublesome to print the embedded flash object.

I think the main problem people are having with this is the receiving of the image data post - see the upload_image method below. Also, teethgrinder's example never really says where to make the post_image() call. So I touch on both in the code below.

Here is an example of the png that is saved when I did this for the chart in the previous example:

OFC Saved Image


Well, let's just get right in to the code.

The controller contains the same code as my last post with only a few minor changes to the index method and the addition of the upload_image method.
In the controller, I have this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class TestItController < ApplicationController
  def index
    # note the user of open_flash_chart_object_from_hash instead of just open_flash_chart_object
    # this allows you to pass in the id of the div you want the the chart to be in
    # this is useful for when we need to findSWF by this id
    @graph = open_flash_chart_object_from_hash("/test_it/chart", :div_name => "my_chart")
  end

  # added to recieve the post data for the OFC png image of the OFC graph
  def upload_image
    name = "tmp_image.png" || params[:name]
    # the save_image method that is provided by the OFC swf file sends raw post data, so get to it like this
    data = request.raw_post
    File.open("#{RAILS_ROOT}/tmp/#{name}", "wb") { |f| f.write(data) } if data
    render :nothing => true
  end

  def chart
    # same code from here - http://pullmonkey.com/2010/01/05/open-flash-chart-ii-x-axis-date-and-time/ 
    ...
  end
end




So just note the use of open_flash_chart_object_from_hash() in the index method, this way we can pass in the id of the div.

In the view, I have this:

1
2
3
4
5
<%= javascript_include_tag 'swfobject.js' %>
<%= @graph %>
<%= save_as_image("http://localhost:3000/test_it/upload_image?name=tmp.png", :id => "my_chart") %>
<br/>
<%= button_to_function "Save Image", "post_image()" %>



Really the only difference from what we would normally have in our view is that I am using the save image setup method that was added to the open flash chart ruby on rails plugin in the last couple hours (as of this post). The save_image method takes some arguments, mainly the url to post the image data to and the id of the chart we setup in the controller.



04 Jan

Open Flash Chart II for Ruby on Rails - Lug Wyrm Charmer


A long time overdue, but I've managed to get everything updated to the new version of Teethgrinder's open flash chart.

I've also started tagging everything, so if you notice any problems trying to do anything from Teethgrinder's examples, then first check that you are using the latest (as of now, that is Lug Wyrm Charmer) - http://github.com/pullmonkey/open_flash_chart/tree/LugWyrmCharmer.

Make sure you are using the latest swf either from the plugin assets directory or from Teethgrinder's downloads.


30 Dec

Using Tumblr as a CMS


Thought you all might like this - http://blog.skizmo.com/post/308406755/use-tumblr-as-your-cms

It is something we sort of dreamed up and it works great as a partial CMS - very much like SimpleCMS where you can specify what exactly on the page needs to be managed by a CMS. This allows you to mix your CMS static content with your dynamic content.


14 Sep

THINning it out


Been having problems with swap space and memory on my slicehost servers.  And it is all apache's and mongrel's fault.  That used to be the cool combination and now it is an ugly, sluggish beast.  Just recently, I switched to nginx (to replace apache) and thin (to replace mongrel).  So far so good, major speed improvements and definitely memory consumption improvements.

I started out by switching everything over the nginx while keeping the mongrels alive, that was actually pretty easy.  Information was available everywhere.

Thinning everything via capistrano took a while, that wasn't as well documented.  Thin was documented, capistrano was documented, but easy solutions as to how to combine the two were difficult to find.

Here's the solution I was able to come up with -

Capistrano

My config for using mongrel used to look something like this -

set :stages, %w(staging production)
set :default_stage, "production"

require "capistrano/ext/multistage"
require "mongrel_cluster/recipes"

set :application, "myapplication.com"
set :user, "appuser"set :repository"http://svn.myapplication.com/myapp/trunk"
set :deploy_to, "/var/www/#{application}"

role :app, application
role :web, application
role :db,  application, :primary => true

set :runner, user
set :keep_releases, 3
set(:mongrel_conf) { "#{current_path}/config/mongrel_cluster.yml" }

deploy.task :after_update_code, :roles => [:web] do
desc "Copying the right mongrel cluster config for the current stage environment."
run "cp -f #{release_path}/config/mongrel_#{stage}.yml #{release_path}/config/mongrel_cluster.yml"
end

... <other things like symlinks>

Now that we are moving from mongrel to thin, no need for two lines in particular, one being the line that requires mongrel_cluster recipes and the other that sets the mongrel_cluster yaml config path.  A third line changes from mongrel_cluster.yml to thin_cluster.yml.  You get something like this:

set :stages, %w(staging production)
set :default_stage, "production"

require "capistrano/ext/multistage"

set :application, "myapplication.com"
set :user, "appuser"

set :repository"http://svn.myapplication.com/myapp/trunk"
set :deploy_to, "/var/www/#{application}"

role :app, application
role :web, application
role :db,  application, :primary => true

set :runner, user
set :keep_releases, 3

deploy.task :after_update_code, :roles => [:web] do
desc "Copying the right mongrel cluster config for the current stage environment."
run "cp -f #{release_path}/config/thin_#{stage}.yml #{release_path}/config/thin_cluster.yml"
end
... <other things like symlinks>

Now we need to implement what mongrel recipes was doing for us, start, stop and restart but in terms of thin (added this to the bottom of my deploy.rb):

namespace :deploy do
desc "Restart the Thin processes on the app server."
task :restart do
run "thin restart -C #{release_path}/config/thin_cluster.yml"
end
desc "Start the Thin processes on the app server."
task :start do
run "thin start -C #{release_path}/config/thin_cluster.yml"
end
desc "Stop the Thin processes on the app server."
task :stop do
run "thin stop -C #{release_path}/config/thin_cluster.yml"
end
end

Here's what my thin_cluster.yml looks like:

---
log: log/thin.log
address: 127.0.0.1
port: 9000
chdir: /var/www/myapp.com/current
environment: production
pid: tmp/pids/thin.pid
user: www-user
group: www-data
servers: 3

That's it and it has worked out nicely so far.


30 Apr

Open Flash Chart II - fully automated


Just as an attention grabber - we are going after this example in this article:

Keeping up

Ok, seeing that the php versions of open flash chart and open flash chart swf files continually change along with with the API (not saying this is a bad thing), I wanted to come up with an even more abstract solution. The goal is to not have to worry when the swf file is released with the latest set of graphs or changes its API. I simply don't want to worry about this method or that method, or this class or that class.

Feedback

This article will sort of act as a tutorial for those interested in metaprogramming and as a set of instructions for those looking to experiment with the latest version of the OFC II Rails Plugin that I am currently toying with. I would like to hear feedback, but just remember that phase 1 of this release will be very basic, meaning none of the ajaxy stuff. It will come, just not yet.

Let's see what we can get away with

I am already using method_missing() for pretty much everything in the OFC II Rails Plugin that is being used now. But every time new classes are added, I have to sit down and basically convert the php class to ruby - just plain tedious, not really what I had planned when I started all this. Ok, so method_missing() was great, but let me introduce (or possibly reintroduce) you to const_missing(), basically method_missing() but instead of methods, we can create classes or modules or other objects on the fly. This will definitely help when the php version gets a new class. Instead of getting hounded to update the rails version to be 100% like the php version, everything will just work, no updates to code required. Well, we hope ! So check this out:



Here is what we did with method_missing():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

module OFC
  class Base
    def method_missing(method_name, *args, &blk)
      case method_name.to_s
      when /(.*)=/   # i.e., if it is something x_legend=
        # if the user wants to set an instance variable then let them
        # the other args (args[0]) are ignored since it is a set method
        self.instance_variable_set("@#{$1}", args[0])
      when /^set_(.*)/
        # backwards compatible ... the user can still use the same set_y_legend methods if they want
        self.instance_variable_set("@#{$1}", args[0])
      else
          if inst = self.instance_variable_get("@#{method_name}")
            inst
          else
            # if the method/attribute is missing and it is not a set method then hmmmm better let the user know
            super
          end
      end
    end
  end
end

This just basically allows me to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13

  class Foo < OFC::Base
  end

  foo = Foo.new

  foo.some_random_attribute = "Hello"  #=> "Hello"
  foo.some_random_attribute  #=> "Hello"
  foo.some_random_undefined_attribute  #=> Method Missing error (calls super)

  # too be like php, for easier conversion
  foo.set_some_random_attribute("Good Bye")  #=> "Good Bye"
  foo.some_random_attribute  #=> "Good Bye"

Along the same lines, I have created an initialize method that takes any argument hash of variable/value pairs and calls variable=() which is handled by method missing as we saw above:

1
2
3
4
5
6
7
8

  class Foo < OFC::Base
  end

  foo = Foo.new(:x_axis => 5, :min => 10, :max => 90, :steps => 5, :elements => ["one", "two"])
  
  foo.x_axis #=> 5
  foo.min #=> 10

Ok, so on to const_missing() and what we can do with that:

1
2
3
4
5
6

  def OFC.const_missing(const)
    klass = Class.new OFC::Base
    Object.const_set const, klass
    return klass
  end

This says that any undefined (missing) constant of OFC should be defined as a new class that inherits from OFC::Base.

So when we say OFC::Foo, that has not been defined, so we will get back class OFC::Foo < OFC::Base;end; which will give us the initialize() method and method_missing() method from above. Let's see how this works:

1
2
3
4
5
6
7
8
9
10
11

  line = OFC::Line.new(:values => [1,2,3,nil,nil,5,6,7])
  line.values #=> [1,2,3,nil,nil,5,6,7]
  line.some_random_variable = "Hello" #=> "Hello"
  line.some_random_variable #=> "Hello"

  stacked_bar_chart = OFC::BarStack.new
  stacked_bar_chart.values = []
  stacked_bar_chart.values << [2,3,4]
  stacked_bar_chart.values << [5, {"val" => 5, "colour" => "#ff0000"}]
  stacked_bar_chart.keys = [{ "colour" => "#C4D318", "text" => "Kiting", "font-size" => 13 } ...]

So it all sort of came together right there. I've shown you all the code that comes with the Rails Open Flash Chart plugin now. No more definining idividual classes, no more trying to keep up with the never ending php version, and no more late nights converting php to ruby (!). About dang time.



Ok, but this is just the beginning, nothing has been set in stone, so like I said, give me your feedback, what works for you and what does not. And, hopefully, I will have solutions for you or you for me.


Example with new version (test version)

I am using rails 2.3.2, but I don't think it will matter what version you are using.

Create your new rails project

1
2
3
4
5

# create a new rails project 
> pullmonkey$ rails testing_it
#<Bunch of stuff is created ....>
> pullmonkey$ cd testing_it/

Install the plugin from the test branch

Note the -r test in this next step. The new version (test version) I am playing with is under the test branch and -r says what branch to pull from.

Also, you can use git:// instead of http:// below, but depending on your firewall restrictions http:// will probably work out best for you.

1
2
3

> pullmonkey$ ./script/plugin install http://github.com/pullmonkey/open_flash_chart.git -r test
# <Bunch more stuff ...>

Create a controller to play in

1
2
3

> pullmonkey$ ./script/generate controller test_it
# <And more stuff >

Get our assets

1
2
3
4
5
6
7

# first we will get swfobject.js
> pullmonkey$ cp vendor/plugins/open_flash_chart/assets/javascripts/swfobject.js public/javascripts/
# next the open flash chart swf (GET whatever is the latest version), right now that is here: http://teethgrinder.co.uk/open-flash-chart-2/open-flash-chart.swf
> pullmonkey$ cd public/
> pullmonkey$ wget http://teethgrinder.co.uk/open-flash-chart-2/open-flash-chart.swf
> pullmonkey$ cd ..

Edit our controller

Notice here that I just include one of the many examples from the plugin's examples directory. Definitely more to follow.

One thing you will notice about the examples, is that the php code is in the comments, so you can see how I would convert from the php examples to ruby. Please feel free to add your own examples, just fork the project.

1
2
3
4
5
6
7
8
9
10

> pullmonkey$ vi app/controllers/test_it_controller.rb
# mine looks like this:
class TestItController < ApplicationController
  include OFC::Examples::AreaHollow

  def index
    @graph = open_flash_chart_object(600,300, "/test_it/area_hollow")
  end
end

Edit our view

1
2
3
4
5

> pullmonkey$ vi app/views/test_it/index.html.erb
# mine looks like this:
<%= javascript_include_tag 'swfobject' %>
<%= @graph %>

Start 'er up

1
2
3
4
5

> pullmonkey$ ./script/server

# browse to the test_it index
http://localhost:3000/test_it

Our example


14 Apr

ECE231 - Spring 2009 - Programming Assignment 4


This is a step-by-step tutorial for this assignment and an explanation of the basics of how it works for those that are having a difficult time understanding or just are stuck somewhere. To view the assignment click here.

So for this assignment we are only going to be doing input and output. So the only header file we need is the iostream library.

1
2
3
4

#include <iostream>
using namespace std;

Defining the Node Class

For the node class we need 5 private variables: type, value, node1, node2, next, a constructor, 5 member functions, and a friend class.

Because most of the functions only return a single variable it would be a waste to have the functions outside the class so I put them all inside the class.

So here is what your class should look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

class node
{
  protected:
    int type;     // type of component
    double value; // value of the component
    int node1;    // first node of the component
    int node2;    // second node of the component
    node *next;   // pointer to the next node in list
  public:
    node(int a, double b, int c, int d)
    {
      type  = a;
      value = b;
      node1 = c;
      node2 = d;
    }

    int getType() { return type; }
    double getValue() { return value; }
    int getNode1() { return node1; }
    int getNode2() { return node2; }
    node *getNext() { return next; }

    friend class circuit;
};

Defining the Circuit Class

For the circuit class we need 2 private variables: first and last, a constructor, a copy constructor, 6 member functions, and a friend function.

For these I will put most of the functions on the outside of the class.

So here is what your class should look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

class circuit
{
  protected:
    node *first; // pointer to first node in list
    node *last;  // pointer to last node in list
    node *getNode(int & , double & , int & , int & );
  public:
    circuit();
    circuit(const circuit & );
    ~circuit();

    void insert(int , double , int , int );
    void insertInFront(node * );
    void insertInBack(node * , node * );
    void insertInMiddle(node * , node * , node * );
    bool remove(int , int );
    bool isEmpty();

    friend ostream & operator << (ostream & , circuit );
};

Writing the Actual Functions for the Circuit Class

First, we have the private function getNode. This function creates a new member of the node class and returns the address to it.

1
2
3
4
5
6
7
8

node* circuit::getNode(int &t, double &v, int &n1, int &n2)
{
  node *temp = new node(t, v, n1, n2);
  assert( temp != 0 );
  return temp;
}

Second, we have the a constructor, a copy constructor, and a class destructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

circuit::circuit()
{
  first = last = 0;
}
circuit::circuit(const circuit &c)
{
  first = last = 0;
  node *nc = c.first;
  while(nc != 0)
  {
    insert(nc->type, nc->value, nc->node1, nc->node2);
    nc = nc->next;
  }
}
circuit::~circuit()
{
  if( !isEmpty() )
  {
    node *nc = first;
    node *temp;
    while(nc != 0)
    {
      temp = nc;
      nc = nc->next;
      delete temp;
    }
  }
}

Next, we have the 6 member functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

void circuit::insert(int t, double v, int n1, int n2)
{
  node *newNode = getNode(t, v, n1, n2);
  node *nc = first;
  node *nc_next = first;
  if(isEmpty())
  {
    first = last = newNode;
    newNode->next = 0;
  }
  else if(first == last)
  {
    if(newNode->node1 < first->node1)
      insertInFront(newNode);
    else if(newNode->node1 > first->node1)
      insertInBack(newNode, first);
    else // if newNode->node1 == first->node1
    {
      if(newNode->node2 < first->node2)
        insertInFront(newNode);
      else
        insertInBack(newNode, first);
    }
  }
  else
  {
    while(nc->next != 0)
    {
      if(newNode->node1 < nc_next->node1)
      {
        if(nc_next == first)
          insertInFront(newNode);
        else
          insertInMiddle(newNode, nc, nc_next);
        break;
      }
      if(newNode->node1 == nc_next->node1)
      {
        if(newNode->node2 <= nc_next->node2)
        {
          if(nc_next == first)
            insertInFront(newNode);
          else
            insertInMiddle(newNode, nc, nc_next);
          break;
        }
      }
      if(newNode->node1 >= nc_next->node1 and nc_next == last)
      {
        insertInBack(newNode, nc_next);
        break;
      }
      nc = nc_next;
      nc_next = nc->next;
    }
  }
}
void circuit::insertInFront(node *n)
{
  n->next = first;
  first = n;
}
void circuit::insertInBack(node *n, node *p)
{
  p->next = last = n;
  n->next = 0;
}
void circuit::insertInMiddle(node *cn, node *p , node *n)
{
  p->next = cn;
  cn->next = n;
}
bool circuit::remove(int n1, int n2)
{
  node *nc = first;
  node *nc_next = first;
  node *temp;
  if( isEmpty() )
    return false;
  while (nc_next != 0)
  {
    if(nc_next != 0 and nc_next->node1 == n1 and nc_next->node2 == n2)
    {
      temp = nc_next;
      nc->next = nc_next->next;
      if(first == last)
        first = last = 0;
      if(nc_next == first)
        first = temp->next;
      if (nc_next == last)
        last = nc;
      delete nc_next;
      return true;
    }
    nc = nc_next;
    nc_next = nc->next;
  }
  return false;
}
bool circuit::isEmpty()
{
  return ( first == 0 and last == 0 );
}

Last, we have a friend function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

ostream & operator << (ostream &os, circuit c)
{
  node *nc = c.first; // node count variable used for looping through list
  int lcv = 1; // loop control variable
  cout << "First: " << c.first << "  Last: " << c.last << endl;
  while (nc != 0)
  {
    os << lcv << ". "
       << "node1: "   << nc->getNode1() 
       << "  node2: " << nc->getNode2()
       << "  type: "  << nc->getType() 
       << "  value: " << nc->getValue() 
       << "  next: "  << nc->getNext() 
       << endl;
    nc = nc->getNext();
    lcv++;
  }
  if(c.first == 0)
    os << "List is empty" << endl;
  return os;
}

Testing your program

Our teacher gave us a test program, however I expanded it a little bit to test a bit more fully.

So here is my test program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

#include <iostream>
#include "yourprogramname.h"
using namespace std;

const int M=7;
const int R=2;

int main()
{
  circuit c, c2, c3;
  int d[M*3] = {1,1,4, 1,1,3, 2,2,3, 1,1,2, 1,5,6, 1,2,5, 3,1,3};
  double v[M] = {10.5, 30.7, 100.4, 20.6, 35.5, 45.9, 60.8};
  int d1[R*8] = {1,2, 5,6, 3,6, 1,4, 1,3, 2,5, 2,3, 1,3};
  int i, j;

  for( i=0,j=0; i<M; i++,j=j+3 )
  {
    cout << i+1 << endl;
    cout << "Inserting new node into list with:" << endl;
    cout << "node1: "   << d[j+1]
         << "  node2: " << d[j+2]
         << "  type: "  << d[j]
         << "  value: " << v[i]
         << endl;
    c.insert( d[j], v[i], d[j+1], d[j+2] );
    cout << "List: " << endl;
    cout << c << endl << endl;
  }
  for( i=0; i<R*8; i=i+2 )
  {
    cout << "Removing node with:" << endl;
    cout << "node1: "   << d1[i]
         << "  node2: " << d1[i+1]
         << endl;
    if( c.remove( d1[i], d1[i+1] ) == false )
      cout << "Node not found" << endl;
    cout << "List: " << endl;
    cout << c << endl << endl;
  }

  cout << "nnMaking List #2:" << endl;
  int d2[M*3] = {2,2,4, 1,1,3, 2,2,3, 1,1,2, 1,5,6, 1,2,5, 3,1,3};
  for( i=0,j=0; i<M; i++,j=j+3 )
  {
    cout << i+1 << endl;
    cout << "Inserting new node into list with:" << endl;
    cout << "node1: "   << d2[j+1]
         << "  node2: " << d2[j+2]
         << "  type: "  << d2[j]
         << "  value: " << v[i]
         << endl;
    c2.insert( d2[j], v[i], d2[j+1], d2[j+2] );
    cout << "List: " << endl;
    cout << c2 << endl << endl;
  }

  cout << "nnMaking List #3:" << endl;
  int d3[M*3] = {2,2,4, 3,3,3, 2,2,3, 1,1,2, 1,5,6, 1,2,5, 3,1,3};
  for( i=0,j=0; i<M; i++,j=j+3 )
  {
    cout << i+1 << endl;
    cout << "Inserting new node into list with:" << endl;
    cout << "node1: "   << d3[j+1]
         << "  node2: " << d3[j+2]
         << "  type: "  << d3[j]
         << "  value: " << v[i]
         << endl;
    c3.insert( d3[j], v[i], d3[j+1], d3[j+2] );
    cout << "List: " << endl;
    cout << c3 << endl << endl;
  }

  return 0;
}


26 Mar

ECE231 - Spring 2009 - Programming Assignment 3


This is a step-by-step tutorial for this assignment and an explanation of the basics of how it works for those that are having a difficult time understanding or just are stuck somewhere. To view the assignment click here.

So for this assignment we are going to be doing a lot of math calculations so we are going to need the include the both the iostream and the cmath libraries. We will also need the value of pi.

1
2
3
4
5
6
7
8
9

#include <iostream>
#include <cmath>
using namespace std;

#define PI 3.141592654
or
const double PI = 3.141592654;

Defining the Complexn Class

For the complexn class we need 2 private variables r and i, 3 constructors, a copy constructor, 4 member functions, 9 overloaded opperators, and 2 friend functions.

Like the previous program we will define everything with in the class and have the actual functions at the bottom.

So here is what your class should look like (keep in mind that this all goes at the top before the main function):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

class complexn
{
  private:
    double r; // real part of the complex number
    double i; // imaginary part of the complex number
  public:
    complexn();
    complexn(double );
    complexn(double , double );
    complexn(const complexn & );

    double complexabs();
    double complexangle();
    complexn complexconj();
    double distance(const complexn & );

    complexn operator + (const complexn & );
    complexn operator - (const complexn & );
    complexn operator * (const complexn & );
    complexn operator / (const complexn & );
    complexn operator = (const complexn & );

    complexn operator ++ ();
    complexn operator ++ (int );
    complexn operator -- ();
    complexn operator -- (int );

    friend ostream & operator << (ostream & , const complexn & );
    friend istream & operator >> (istream & , complexn & );
};

Writing the Actual Functions for the Complexn Class

First we have the 3 constructors and the copy constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// takes no arguments and sets r and i to 0.0
complexn::complexn()
{
  r = i = 0.0;
}
// takes 1 argument and sets r to the argument and i to 0.0
complexn::complexn(double real)
{
  r = real;
  i = 0.0;
}
// takes 2 arguments and sets r to the first and i to the second
complexn::complexn(double real, double imag)
{
  r = real;
  i = imag;
}
// this is a copy constructor that dereferences the complexn variable if it is referenced
complexn::complexn(const complexn &c)
{
  r = c.r;
  i = c.i;
}

Next, we have the 3 member functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

// takes no arguments and returns the distance from the 0 as a double
double complexn::complexabs()
{
  return sqrt(pow(r,2.0) + pow(i,2.0));
}
// takes no arguments and returns the angle of the complex point as a double in radians
double complexn::complexangle()
{
  double angle; // angle of coordinate from positive x axis
  angle = atan(r / i);
  if(r < 0 and i >= 0)
    return PI - abs(angle);
  if(r < 0 and i < 0)
    return -(PI - abs(angle));
  return angle;
}
// takes no arguments and returns the conjugate of the complex number as a complexn class
complexn complexn::complexconj()
{
  complexn temp = *this; // complex number used for calculations
  temp.i *= -1;
  return temp;
}
// takes one complexn type argument and returns the distance between the argument and the current instance
double complexn::distance(const complexn &temp)
{
  return sqrt(pow(temp.r -r, 2.0) + pow(temp.i - i, 2.0));
}

Next, we have the 9 overloaded operators:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

complexn complexn::operator + (const complexn &temp)
{
  complexn cn; // complex number used for calculations
  cn.r = r + temp.r;
  cn.i = i + temp.i;
  return cn;
}
complexn complexn::operator - (const complexn &temp)
{
  complexn cn; // complex number used for calculations
  cn.r = r - temp.r;
  cn.i = i - temp.i;
  return cn;
}
complexn complexn::operator * (const complexn &temp)
{
  complexn cn; // complex number used for calculations
  cn.r = r * temp.r - i * temp.i;
  cn.i = r * temp.i + i * temp.r;
  return cn;
}
complexn complexn::operator / (const complexn &temp)
{
  complexn cn; // complex number used for calculations
  cn.r = (r * temp.r + i * temp.i) / (pow(temp.r, 2.0) + pow(temp.i, 2.0));
  cn.i = (i * temp.r - r * temp.i) / (pow(temp.r, 2.0) + pow(temp.i, 2.0));
  return cn;
}
complexn complexn::operator = (const complexn &temp)
{
  r = temp.r;
  i = temp.i;
  return *this;
}
complexn complexn::operator ++ ()
{
  r += 1;
  return *this;
}
complexn complexn::operator ++ (int x)
{
  complexn temp = *this;
  r += 1;
  return temp;
}
complexn complexn::operator -- ()
{
  r -= 1;
  return *this;
}
complexn complexn::operator -- (int x)
{
  complexn temp = *this;
  r -= 1;
  return temp;
}

Last, we have the 2 friend functions:

1
2
3
4
5
6
7
8
9
10
11
12

ostream & operator << (ostream &os, const complexn &temp)
{
  os << temp.r << " + " << temp.i << "i";
  return os;
}
istream & operator >> (istream &is, complexn &temp)
{
  is >> temp.r >> temp.i;
  return is;
}

Testing Your program

I wrote a fairly good program for testing this complexn class.

To test your program copy your program to [name].h file and in the main.cpp file change the header file at the top to match your file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

#include <iostream>
#include "yourprogram.h" // the name of your comlexn header file goes here

using namespace std;

int main()
{
  complexn c1;
  complexn c2(1);
  complexn c3(3, -5);
  complexn c4, c5, c6;

  cout << "Complex Numbers: " << endl;
  cout << "  C1: " << c1 << endl;
  cout << "  C2: " << c2 << endl;
  cout << "  C3: " << c3 << endl;

  cout << "nEnter values for C1: ";
  cin >> c1;
  cout << "  You enetered: " << c1 << endl;
  cout << "Enter values for C2: ";
  cin >> c2;
  cout << "  You enetered: " << c2 << endl;
  cout << "Enter values for C3: ";
  cin >> c3;
  cout << "  You enetered: " << c3 << endl;

  cout << "nDistances from origin: " << endl;
  cout << "  C1(" << c1 << "): " << c1.complexabs() << endl;
  cout << "  C2(" << c2 << "): " << c2.complexabs() << endl;
  cout << "  C3(" << c3 << "): " << c3.complexabs() << endl;

  cout << "nConjugates:" << endl;
  cout << "  C1(" << c1 << "): " << c1.complexconj() << endl;
  cout << "  C2(" << c2 << "): " << c2.complexconj() << endl;
  cout << "  C3(" << c3 << "): " << c3.complexconj() << endl;

  cout << "nDistances between:" << endl;
  cout << "  C1(" << c1 << ") and C2(" << c2 << "): " << c1.distance(c2) << endl;
  cout << "  C1(" << c1 << ") and C3(" << c3 << "): " << c1.distance(c3) << endl;
  cout << "  C2(" << c2 << ") and C3(" << c3 << "): " << c2.distance(c3) << endl;

  cout << "nAddition:" << endl;
  cout << "  C1(" << c1 << ") + C2(" << c2 << "): " << c1 + c2 << endl;
  cout << "  C1(" << c1 << ") + C3(" << c3 << "): " << c1 + c3 << endl;
  cout << "  C2(" << c2 << ") + C3(" << c3 << "): " << c2 + c3 << endl;

  cout << "nSubtraction:" << endl;
  cout << "  C1(" << c1 << ") - C2(" << c2 << "): " << c1 - c2 << endl;
  cout << "  C1(" << c1 << ") - C3(" << c3 << "): " << c1 - c3 << endl;
  cout << "  C2(" << c2 << ") - C3(" << c3 << "): " << c2 - c3 << endl;

  cout << "nMultiplication:" << endl;
  cout << "  C1(" << c1 << ") * C2(" << c2 << "): " << c1 * c2 << endl;
  cout << "  C1(" << c1 << ") * C3(" << c3 << "): " << c1 * c3 << endl;
  cout << "  C2(" << c2 << ") * C3(" << c3 << "): " << c2 * c3 << endl;

  cout << "nDivision:" << endl;
  cout << "  C1(" << c1 << ") / C2(" << c2 << "): " << c1 / c2 << endl;
  cout << "  C1(" << c1 << ") / C3(" << c3 << "): " << c1 / c3 << endl;
  cout << "  C2(" << c2 << ") / C3(" << c3 << "): " << c2 / c3 << endl;

  cout << "nIncrementing:" << endl;
  cout << "  C1 =  " << c1   << endl;
  cout << "  C1++: " << c1++ << endl;
  cout << "  C1 =  " << c1   << endl;
  cout << "  ++C1: " << ++c1 << endl;
  cout << "  C1 =  " << c1   << endl;

  cout << "  C2 =  " << c2   << endl;
  cout << "  C2++: " << c2++ << endl;
  cout << "  C2 =  " << c2   << endl;
  cout << "  ++C2: " << ++c2 << endl;
  cout << "  C2 =  " << c2   << endl;

  cout << "  C3 =  " << c3   << endl;
  cout << "  C3++: " << c3++ << endl;
  cout << "  C3 =  " << c3   << endl;
  cout << "  ++C3: " << ++c3 << endl;
  cout << "  C3 =  " << c3   << endl;

  cout << "nDecrementing:" << endl;
  cout << "  C1 =  " << c1   << endl;
  cout << "  C1--: " << c1-- << endl;
  cout << "  C1 =  " << c1   << endl;
  cout << "  --C1: " << --c1 << endl;
  cout << "  C1 =  " << c1   << endl;

  cout << "  C2 =  " << c2   << endl;
  cout << "  C2--: " << c2-- << endl;
  cout << "  C2 =  " << c2   << endl;
  cout << "  --C2: " << --c2 << endl;
  cout << "  C2 =  " << c2   << endl;

  cout << "  C3 =  " << c3   << endl;
  cout << "  C3--: " << c3-- << endl;
  cout << "  C3 =  " << c3   << endl;
  cout << "  --C3: " << --c3 << endl;
  cout << "  C3 =  " << c3   << endl;

  c4 = c1;
  c5 = c2;
  c6 = c3;

  cout << "nEquals:" << endl;
  cout << "  C4 = C1(" << c1 << "): " << c4 << endl;
  cout << "  C5 = C2(" << c2 << "): " << c5 << endl;
  cout << "  C6 = C3(" << c3 << "): " << c6 << endl;

  c1 = complexn ( 1, 1);
  c2 = complexn (-1, 1);
  c3 = complexn (-1,-1);
  c4 = complexn ( 1,-1);
  c5 = complexn ( 0, 1);
  c6 = complexn (-1, 0);
  cout << "nAngles:" << endl;
  cout << "  C1(" << c1 << "): " << c1.complexangle() << endl;
  cout << "  C2(" << c2 << "): " << c2.complexangle() << endl;
  cout << "  C3(" << c3 << "): " << c3.complexangle() << endl;
  cout << "  C4(" << c4 << "): " << c4.complexangle() << endl;
  cout << "  C5(" << c5 << "): " << c5.complexangle() << endl;
  cout << "  C6(" << c6 << "): " << c6.complexangle() << endl;

  return 0;
}


10 Mar

Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support


I don't do too much with php these days, and really haven't since I found rails many years ago. But I figured I would give magento a try, just for fun. Most of it worked, but I continually came across this PCRE error - the full error that I go was:


Warning: preg_match_all() [function.preg-match-all]: Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support at offset 0  ...

Ok, loads and loads of research led no where, or at least no where that I was willing to go. I tried so hard to find a solution that didn't require me recompiling apache ... well no such luck. I am using slicehost's ubuntu 8.04, so I took the dpkg approach to help make things simple.


Well, I am sure you have found out by now that apache comes with its own version of pcre built in (version 5). This version does not come with UTF-8 support. The trick is to tell apache to use an external system package of pcre. This requires the slightest bit of reconfiguring of apache.

Initially, my pcre looked like this (notice the version of 5.0...):



As mentioned earlier this is a pretty good indicator that your pcre is the built-in apache version. This is not good.



Ok, the solution is not too bad. Compared to this article, which I learned a few things from, it is much simpler. One thing, you will note in the article is the use of --with-pcre=/usr - this is quite different than the --with-pcre=yes that apache2 comes configured with from gusty.

So the solution is to make that change by doing this:

1) Get the source code:

1
2
3
mkdir apache_src
cd apache_src/
apt-get source apache2

2) Modify the configuration (specifically the AP2_COMMON_CONFARGS in debian/rules)
Once the source is downloaded you should have several files and a directory. Edit the debian/rules files from within the apache directory. The only change that is needed is to find the line that says --with-pcre=yes and change it to say --with-pcre=/usr.

This, of course, assumes that you installed pcre and it lives in /usr/(bin,lib ...):

1
2
vi apache2-2.2.4/debian/rules # make those changes
./apache2-2.2.4/debian/rules

3) Install build dependencies for apache:


sudo apt-get build-dep apache2

4) Now build the package:

1
2
3
4
cd apache2-2.2.4/
# you may need to install fakeroot for this:
sudo apt-get install fakeroot 
dpkg-buildpackage -rfakeroot -uc -b

5) Install the new apache package:

1
2
cd ..
sudo dpkg -i apache2_2.2.4-3ubuntu0.1_all.deb



Voila, now look what I have:



That should be it.



Good luck.


23 Feb

ECE231 - Spring 2009 - Programming Assignment 2


This is a step-by-step tutorial for this assignment and an explanation of the basics of how it works for those that are having a difficult time understanding or just are stuck somewhere. To view the assignment click here.

So for this assignment we are going to be doing a lot of math calculations so we are going to need the include the both the iostream and the cmath libraries. We will also need the value of pi.

1
2
3
4
5
6
7
8

#include <iostream>
#include <cmath>

#define PI 3.14159
or
const double PI = 3.14159;

Defining the Coordinate Class

For the coordinate class we need 2 private variables x and y, 3 constructors, and 11 member functions.

The way you do the constructors and member functions can be done 2 different ways. You can either do them inside the class, or you can define them inside the class, like you do prototypes, and then have the actual functions at the bottom of your code. I like to define them and then put the functions at the bottom, making the code a little bit easier to read so that is the way that I'll show you, but if you want to do it the other way then just do it how you normally would with a regular function.

So here is what your class should look like (keep in mind that this all goes at the top before the main function):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class coordinate
{
  private:
    double x;  // x value of the coordinate point
    double y;  // y value of the coordinate point
  public:
    coordinate(); // 1st constructor requiring that no arguments are passed
    coordinate(double ); // 2nd constructor requiring that only 1 argument is passed
    coordinate(double , double ); // 3rd constructor requiring that 2 arguments are passed

    void set(double , double ); // sets both values and requires 2 arguments to be passed
    void setx(double ); // sets x value and requires 1 argument to be passed
    void sety(double ); // sets y value and requires 1 argument to be passed
    void read(); // allows user to input both x and y values 
    void print(); // prints out the coordinate point in "(x, y)" form
    double distancezero(); // calculates distance of point from zero and returns the value
    double distancetwo(coordinate ); // calculates distance between 2 points (current instance and coordinate value passed) and returns the value
    double ranglezero(); // calculates the angle of the coordinate in radians and returns the value
    double danglezero(); // calculates the angle of the coordinate in degrees and returns the value
    int quadrant(); // find what quadrant the coordinate is in and returns the value
    void midpoint(coordinate ); // calculates the midpoint between 2 points (current instance and coordinate value passed) and prints the value as a coordinate
};

Writing the Actual Functions for the Coordinate Class

Since we are not actually writing the functions in the same place we are doing the class we will write them at the bottom after the main function. However, to do this we will need a little more than what we would with regular functions. For member functions we have to define what class the function is actually a member of. To do this we have to do coordinate::[function]().

For example, here are the 3 constructors for the coordinate class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// takes no arguments and sets x and y to 0
coordinate::coordinate()
{
  x = y = 0;
} 
// takes 1 argument and sets x and y to that value
coordinate::coordinate(double a)
{
  x = y = a;
} 
// takes 2 arguments and sets the corresponding x and y to those values
coordinate::coordinate(double a, double b)
{
  x = a;
  y = b;
}

Next, we have the member functions. The first 3 are the set functions. These allow the user to set the values of either the x or the y or both together.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// take 2 arguments and sets the corresponding x and y to those values
void coordinate::set(double a, double b)
{
  x = a;
  y = b;
}
// takes 1 argument and sets the x to that value
void coordinate::setx(double a)
{
  x = a;
}
// takes 1 argument and sets the y to that value
void coordinate::sety(double b)
{
  y = b;
}

Next, is the read and print functions. All we want the read to do is to do a cin of the 2 values (x and y). The print is just the opposite. All it does is do a cout of the x and y values in the (x, y) format.

1
2
3
4
5
6
7
8
9
10
11
12

// takes no arguments and reads in the x and y values from the screen
void coordinate::read()
{
  cin >> x >> y;
}
// takes no arguments and prints the x and y values in (x, y) format
void coordinate::print()
{
  cout << "(" << x << ", " << y << ")";
}

Next, we have the distance functions. distanczero calculates the distance of the current instance coordinate from 0. distancetwo calculates the distance between 2 points (the current instance and the coordinate passed in).

1
2
3
4
5
6
7
8
9
10
11
12

// takes no arguments and returns the distance of the current instance from zero
double coordinate::distancezero()
{
  return sqrt(x * x + y * y);
}
// take 1 argument and calculates the distance between them
double coordinate::distancetwo(coordinate pt)
{
  return sqrt(pow(x - pt.x, 2.0) + pow(y - pt.y, 2.0));
}

Next, we have the angle functions. ranglezero uses the function in the math library atan()(arc tangent) to find the angle in radians from the positive x axis. danglezero does the same thing but converts the value from radians to degrees. To convert from radians to degrees you multiply the value by 180 / pi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

// takes no arguments and returns the angle of the coordinate from the positive x axis in radians
double coordinate::ranglezero()
{
  double angle; // angle of coordinate from positive x axis
  if(x == 0) // if x == 0 then you will get a domain error so compute angle manually
  {
    if(y > 0) return PI / 2;
    if(y < 0) return -PI / 2;
    if(y == 0) return 0;
  }
  angle = atan(y / x);
  if(x < 0 and y >= 0)
    return PI - abs(angle);
  if(x < 0 and y < 0)
    return -(PI - abs(angle));
  return angle;
}
// takes no arguments and returns the angle of the coordinate from the positive x axis in degrees
double coordinate::danglezero()
{
  double angle; // angle of coordinate from positive x axis
  if(x == 0) // if x == 0 then you will get a domain error so compute angle manually
  {
    if(y > 0) return 90;
    if(y < 0) return -90;
    if(y == 0) return 0;
  }
  angle = atan(y / x) * 180 / PI;
  if(x < 0 and y >= 0)
    return 180 - abs(angle);
  if(x < 0 and y < 0)
    return -(180 - abs(angle));
  return angle;
}

Next, we have the quadrant function. This looks at whether the x and y values are positive or negative to determine which quadrant the coordinate is in. It will return the number of the quadrant as an integer 1-4 and 0 if the coordinate is (0, 0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14

int coordinate::quadrant()
{
  if(x > 0 && y >= 0)
    return 1; // return quadrant 1
  if(x <= 0 && y > 0)
    return 2; // return quadrant 2
  if(x < 0 && y <= 0)
    return 3; // return quadrant 3
  if(x >= 0 && y < 0)
    return 4; // return quadrant 4
  return 0;   // return 0 if point is (0, 0)
}

Last, we have the midpoint function. you will need to pass this function a coordinate instance and it will calculate the midpoint between the current instance and the passed instance and print the coordinate instance.

1
2
3
4
5
6
7
8
9

void coordinate::midpoint(coordinate pt)
{
  coordinate np; // new coordinate point
  np.x = (x + pt.x) / 2.0;
  np.y = (y + pt.y) / 2.0;
  np.print();
}

Now all you have to do is test each constructor and member function to make sure that everything is working properly.