Showing posts with label integration. Show all posts
Showing posts with label integration. Show all posts

Tuesday, March 9, 2010

NetBeans and Qt

Introduction
I originally started this blog with the idea of building an Android application and recording my experience.  School, work and other activities have sent this in a totally different direction.  I still plan on recording my development experiences here, the actual topics, though, have changed.

On to the reason for this post.  I was recently asked if I would be interested in doing some work writing an interface to a financial trading system.  The gist of the project is this - write an application that polls the market data specified, runs an algorithm against it, and notifies the user if the algorithm meets a certain threshold.  The makers of the software have conveniently supplied an API to read their data streams.  In fact, they have supplied an API for C++, Java, and POSIX.  Being a native Java developer, you would think that I would immediately go for that solution to the problem.  The truth is, if I end up doing this, that will be my likely path.

When I got to thinking about the problem domain, however, I thought I should be prepared for a different build. First off, consider the basic description - get market data, perform analysis, give result.  This is clearly intended to give the user the proper information to make a decision about a trade, and then act on it.  Clearly, the faster the application works, the better.  Now consider an application running in the JVM.  Basic operations between Java and other languages, given the high quality JIT implementations these days, is minimal.  I wouldn't expect to see a significant performance hit using Java as opposed to C++.  The second consideration, though, is garbage collection.  If I implement the system poorly, there may be periodic delays due to garbage collection. Heck, if I implement it correctly there may be delays.  Now I have to consider whether I think this will actually be an issue, and the answer is, probably not.  I can take actions to minimize GC and optimize the return of the results.  This got me thinking, though.  It would be nice to be able to write this in C++.  So I decided to make sure that I could.

The Development Stack


After some brief research I decided to go with the Qt library on NetBeans.  You can learn more about Qt here.  Why Qt and NetBeans?  Well Qt is an LGPL, cross platform component library with a neat Visual editor.  NetBeans is a high-quality Open Source IDE, with a lot of support for C++.  I could have gone with Eclipse, which is my primary IDE, but NetBeans has always had a leg up on this type of development in my book.

The Setup


NetBeans even has a nice tutorial on how to configure and set up a Qt project.  Too bad it is no longer accurate (Nod to Steve, "Yes this is another case of an OS project documentation being out-of-date").  Here is what I found:

  • The tutorial instructs you to install mingw, qt and msys separately.  This is not needed if you are using 4.6.2.  In fact, this won't work.  
  • This post suggests that Qt changed the version of the compiler they use in the latest bundle, and that they include mingw with the distribution.  
So, here is my short list of steps you need to follow to get Qt working with NetBeans:
  1. Make sure you have the JDK and NetBeans installed
  2. Make sure you have NetBeans C/C++ plugin 
  3. Install msys1.0 (As easy as following the defaults in the installer)
  4. Get the Qt installer, Full version. Follow the defaults  (The NetBeans tutorial says to only download the Qt libraries)
See how easy that was?  Much easier than the NetBeans tutorial suggested.  To make sure you can compile a  Qt project, there is one configuration item left.  Make a MinGW_Qt Tool Collection. 
  1. Go toTools->Options, C/C++.
  2. Click Add...
  3. Select the Qt mingw installation as your base directory (mine is at: c:\Qt\2010.02.1\mingw\bin
  4. Select mingw as your tool collection family.  Your collection configuration should look like the screen shot below



Build and Run


You should now be able to build and run the sample from the NetBeans tutorial.  Remember to make sure that your Qt Tool collection is the collection used for the build.

Sunday, January 10, 2010

Paypal PDT

I thought I would follow up my previous post with one that points out some good practices, and potential pitfalls when using really simple interfaces.  The DS Volatility Trends Web site is going to use the Paypal PDT option, where a user will be redirected back to the DS Volatility Trends Web site after payment is complete. The API is VERY simple.  You tell Paypal which page to redirect to, and it redirects to that page with a single get paramer: tx.  You then use this parameter, and your user key to get more information about the tx and to verify it for security purposes.  Here is the output of the response for a first test, run against the sandbox, with user keys omitted:


SUCCESS
mc_gross=5.00
protection_eligibility=Eligible
address_status=confirmed
payer_id=
address_street=1+Main+St
payment_date=09%3A30%3A43+Jan+09%2C+2010+PST
payment_status=Completed
charset=windows-1252
address_zip=95131
first_name=Test
mc_fee=0.45
address_country_code=US
address_name=Test+User
subscr_id=
payer_status=verified
business=
address_country=United+States
address_city=San+Jose
payer_email=
txn_id=8NJ4974863519050H
payment_type=instant
last_name=User
address_state=CA
receiver_email=
payment_fee=0.45
receiver_id=
txn_type=subscr_payment
item_name=DS+Volatility+Trends+Newsletter
mc_currency=USD
residence_country=US
transaction_subject=
payment_gross=5.00



Here is a sample after I inserted a custom value:

SUCCESS
mc_gross=5.00
protection_eligibility=Ineligible
address_status=confirmed
payer_id=
address_street=1+Main+St
payment_date=09%3A06%3A15+Jan+10%2C+2010+PST
payment_status=Pending
charset=windows-1252
address_zip=95131
first_name=Test
address_country_code=US
address_name=Test+User
subscr_id=
custom=12631431526791
payer_status=verified
business=
address_country=United+States
address_city=San+Jose
payer_email=
txn_id=0LG419336A6914908
payment_type=echeck
last_name=User
address_state=CA
receiver_email=
receiver_id=
pending_reason=echeck
txn_type=subscr_payment
item_name=DS+Volatility+Trends+Newsletter
mc_currency=USD
residence_country=US
transaction_subject=
payment_gross=5.00



Can you see the potential issue?  Inexperienced developers often take the first result set and start parsing it, line by line.  Some pseudo-code to represent this:

//Code has other problems besides the one being highlighted...

//Get String from stream...
String[] values = returnString.split("\n");
//now get the values of each line, assuming they are in the correct order
mcGross = values[0].split("=")[1];
protectionEligibility = values[1].split("=")[1];
//continue with all other values..


The code above would break as soon as the new variable is added, since the variable is returned in the middle of the list, all variables after 'custom' will be offset by 1 in the index.  In addition, I don't see any specific guarantee that the order will always be the same (Although that would be a good practice for Paypal to implement...).  At any rate, it is better to handle the values in an order-neutral way.  In Java, I would do this by parsing the string and creating name-value pairs in a Map.  This requires a little more code up front, but will save lots of potential errors down the road.


//Better but still needs work to be robust....


Map values = new HashMap
String[] values = returnString.split("\n");
for(int i=0; i < values.length; i++ ) {
    String[] thisValue = values[i].split("=");
    values.add(thisValue[0], thisValue[1]);
}
//Now values has ALL the values if new ones are added or the order changes,
//we don't care.  We're also sure we set the value with the right key
mcGross = values.get("mc_gross");


As you can see, with the second implementation, the code will still work just fine with the new 'custom' variable returned in the results.  The order of the variables is no longer important, and frankly, I think it is more expressive - mc_gross key is clearly being tied to the mcGross variable.