Impact factor for posts is a measurement of importance.

Impact factor for users reflect their authority, reputation and contribution on a particular topic.

Rating reflects the quality of posts.

Rating on Voofie is not a simple average of all ratings, but a weighted average of rating, weighted by the impact factor of users who rated.

Explore exciting communities of

Tutorial on using MathOO

05 Nov 10

This is a basic tutorial about using MathOO, the internal structure of MathOO, and how MathOO works.

Bookmark and Share

Content

Introduction

In this tutorial, I will teach the basic of MathOO by writing a simple UnitTest class, use it to test the functionality of MathOO itself.

Basics

MathOO adds object orientation to Mathematica. Therefore this tutorial assumes you understand basic concepts of object-oriented programming.

To use MathOO, you first need to run:

Needs["MathOO`"]

In order to load the library and necessary functions.

The most important concept in OO is class. So, let's define a class first.

NewClass[UnitTest];

This defines UnitTest to be a new class.

Every class needs to have its own constructor (or any of its parents). Therefore let us define one first:

UnitTest.$init$[self_, file_: Null] := (self.command = 
If[file === Null, {},
ReadList[file, Record, RecordSeparators -> {"\n\n"}][[2 ;;]]];
);

The constructor name is called $init$. $name$ is a convention used in MathOO. It indicates the simple is for internal use. It is just analogous to the constructor __init__ in Python. For your own private method, use $method instead. MathOO does not have the concept of private method, and it's up to you to follow the convention.

The above code define the UnitTest.$init$ to be a function with two variables: self and file. self stands for the object itself. For every class method, it is called with the object as the first argument. It is also a convention to use self as the object itself, as in Python too. file is an optional argument. If supplied, the function will look for the file, open it as text file, and split the file into records with "\n\n" as the split characters. Each of the record contributes to one test. And all tests are stored in the object attribute self.command.

UnitTest.addTest[self_, e_] := (AppendTo[self.command, e])

Now define another function UnitTest.addTest, so that you can add individual test as string.

UnitTest.run[self_] := Module[{l, fail, u},
fail = {};
Do[
e = Catch[ToExpression[c]];
If[e =!= True, AppendTo[fail, c]]
, {c, self.command}];
l = Length[self.command];
If[Length[fail] == 0, Print["All Tests Past!"], Print[fail]];
Print[ToString[l - Length[fail]] <> "/" <> ToString[l] <>
" tests past."]
]

To run the test, we need to define the function UnitTest.run. This function convert each of the string stored in self.command, and then evaluate it using ToExpression. Each test should output the value True, otherwise, it is considered failed. This function will print out the failed tests, and the number of tests past.

Usage of UnitTest

UnitTest can be used in two ways:

Using a file

Create a new package file (test.m) using Mathematica, the paste the following code into it and save.

BeginPackage["Testing`", {"MathOO`"}];
NewClass[h];
g;
Begin["`Private`"];
static[h.c];
h.c[x_] := x^2;
h.$init$[self_]:=Return[];
g = new[h][];
g.a=1;
g.b=2;
g.d=3;
End[];
EndPackage[];
h.c[5] == 25

g.a==1

g.b==2

g.d==3

g.c[6]==36

o = Object;
NewClass[A1, o];
NewClass[B1, o];
NewClass[C1, o];
NewClass[D1, o];
NewClass[E1, o];
NewClass[K1, A1, B1, C1];
NewClass[K2, D1, B1, E1];
NewClass[K3, D1, A1];
NewClass[Z, K1, K2, K3];
Z["$parentOrder$"] == {K1, K2, K3, D1, A1, B1, C1, E1, Object}

a={1,2};b={3,4};a.b==11

A1.a={3,4};A1.a.b==25

K1.g = {1, 2, 3};
K1.g[[2]] = 5;
K1.g == {1, 5, 3}

K1.g=.;
ToExpression[K1["g"],StandardForm,ValueQ]==False

a=new[Object][];
a.b=5;
u=a["b"];
delete[a.b];
Catch[a.b]=="No attributes Error :b" && !ToExpression[u,StandardForm,ValueQ]

a.b=new[Object][];
a.b.c=5;
delete[a.b.c];
Catch[a.b.c]=="No attributes Error :c"

Now, each of the empty line indicates an individual test.

In another notebook, type:

unit = new[UnitTest]["test.m"];
unit.run[];

It will output:

All Tests Past!

12/12 tests past.

Showing that all the tests past.

Adding individual test

Now, you can add individual test like this:

unit.addTest["x=new[Object][];
x.b=1;
x.b==1"];

Your test entered must be a string. Therefore if your test code has special characters such as ", they needed to be escaped, which I found quite troublesome.

0 Comments

Please login to post comment.

What is Voofie?

Voofie organizes knowledge, discovers useful resources and recognizes knowledgable users.

Bookmark your blog in Voofie to get more traffic as well as building a reputation in your field!

Explore more about it. Become a member—our FREE Registration takes just seconds.

Page Info
3Impacts
0/0 rates
960
Your Rating:
Version: 3
Last update: 05 Nov 10
History Permalink
Author
Avatar for ross_tang

Ross Tang (ross_tang)

Degree in Physics and Mathematics, Master in Physics
香港

  • MathOO
  • 0