Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Wednesday, June 9, 2010

Perils of a Polyglot - part 2

This is part 2 of my Perils of a Polyglot series. I looked at tokens to mark identifiers ($ vs @) and where to put semicolons (;) to terminate statements. I'll continue this rant looking at other pet hates.

3. if, elseif, else if, elif, end if, then, else:
This is probably a point about scope, whitespace and indentation (I'll whinge about that later). Different programming languages have different ways of doing pretty much the same thing. I must say the most annoying of them all I find is Python. Why? First, 'elif' for 'elseif'. Second, parenthesis outside the condition is optional. That may be convenient but I always pause a second thinking is it right?

if request == "good":
#do something good
elif request == "bad":
#do something bad
else:
#do nothing

You can also do:

if (abooleanVariable):
#do somethihing

VB.NET takes the Pseudo code analogy a bit to serious for me. If ... Then ... ElseIf .. Then .. End If. I always wonder, "If End If is two words, why is ElseIf one word?". Another interesting point is the fact that an If statement spanning a single line does not need an "End If". Example below:

If Not anObject Is Nothing Then anObject.ToString()

VB.NET also brings you niceties such as no parentheses around the conditions and real worlds for the boolean operators (And, Not). Thankfully the Visual Studio IDE should keep you from straying with its auto correct features that include correcting the case of reserved keywords. Nice.

Finally, how the major programming languages handle scope within conditional statements (This could be repeated when b***ching about indentation and whitespace) :

Curly Braces:
  1. Java
  2. C++
  3. C#
  4. PHP
  5. Javascript

The Rest:
  1. Python (Indentation)
  2. Ruby (Keywords: end)
  3. VB.NET (Keywords: Then, EndIf)
Enough about conditionals, I'll try cover the rest of the issues in one post next time.

Tuesday, June 8, 2010

Perils of a Polyglot

A polyglot is linguist - a person who speaks more than one language. Most programmers worth their salt tend to be polyglots in the never ending quest to improve productivity and I'm no different. My day-to-day programming is most in Java and .NET languages VB.NET and C# as I'm mostly doing enterprise development and integration work. My website runs on Joomla! in PHP and I occasionally write some modules for it. The rest of the small projects I work on are some Python (for Google App Engine), Ruby (on Rails) and I'll include Javascript because with node.js and coffee script, I'm doing quite a bit of Javascript.

One of the greatest pains of jumping between different programming languages is the different syntax rules and the obscure error messages you get when you violate these rules. You stare at the code, the error message and nothing makes sense, especially if you are not using an IDE. It was when I was facing such a mistake that I got the idea for this post. So I'll start with that.

1. In PHP variables are denoted with '$' not '@'.
You can guess that I'd been doing some Ruby programming before this. The code I wrote was:

@usr = new StdClass();

The error message was 'Parse error: syntax error, unexpected '=' in on line '. How cryptic is that! I should have typed:

$usr = new StdClass();

However, just @usr; is a valid PHP statement!

2. Where to put those semicolons?
Semicolons are neat statement delimiters. Where to put them and where not to is an error that's easy to make and easy to pick up but worth a mention.

Of the programming languages I use the following use semicolons:
  1. Java
  2. Javascript
  3. C++
  4. C#.NET
  5. PHP
And the languages that don't:
  1. Visual Basic .NET (and VB6)
  2. Python
  3. Ruby
Next post I'll look at the "if, elseif, else if, elif, end if, then" dilemma, Case Sensitivity, Whitespace (tabs vs space), Comments and much more. Share your pain in the comments.

Monday, April 19, 2010

Math for Software Engineers

I've recently gotten into TopCoder (don't ask me where I've been all this time). As a software engineer of about 7+ years, I was quite keen to find out where I stacked up in the programming stakes. I've programmed mostly in Java, so that was the language I chose to use in practice area of the Arena. I should also disclose that I got a tip to attempt some of the division 1 and 2 problems from a Google page about preparing for their interviews. This sparked my curiosity even further.

After starting the Arena (TopCode should have a UI contest to find a more user friendly place to show link to the jnlp. At the footer seems an odd place to have a link that is used frequently) I went into one of the practice rooms and picked a problem related to gambling. TopCoder does not allow unauthorized reproduction of their problems, so I won't violate their copyright. The problem can be found in practice room SRM 144 Div 1.

The crux of the problem is to find out how many combinations of a particular set of items that can be selected from another set of items. For example, if you have to pick 2 numbers from 1-10 inclusive, how many combinations can you include? What if the order is important (i.e. the second number you pick must be greater than the first)? What if the numbers must be unique (i.e. no repititions)? What if both the order and unique rules are necessary?

While I was intrigued with the logical challenge of solving this puzzle, I wondered whether this has a place as a problem for a software engineer. I suspect, depending on how the client has explained this problem (you would have to see the post for the problem from TopCoder) it either becomes a computer science or mathematical problem rather than one about building software. Many computer solutions are replacements for manual processes so sometimes it is necessary to ask the client, "What are you doing currently to solve this?" It could however be a new problem and it is unreasonable for the engineer to tell the client, "Sorry, I can't quite remember my high school math."

The solution to the problem required 4 routines:
  1. A method to calculate exponentials. In java - Math.pow is sufficient.
  2. A method to calculate permutations.
  3. A method to calculate factorials.
  4. A method to calculate binomial_coefficient.

Exponentials
Exponentials can be used to calculate the number of possibilities without any rules regarding order or uniqueness. For the example of 10,2 the number of possibilities is 100.


Permutations
From wikipedia, a permutation of a set of values is an arrangement of those values into a particular order. Going back to the original problem of picking 2 numbers between 1-10, regardless of order and ensuring the numbers are unique (i.e. 1,2 is valid but 2,2 is invalid), calculating the number of permutations of the 10 integers with 2 options for each.

  1. private long permutation(int n, int opts)
  2. {
  3. long result = 1;
  4. for (int idx = 0; idx < opts; idx++)
  5. result *= (n - idx);
  6. return result;
  7. }
Factorials
Factorials are a little more interesting than permutations. The factorial of a positive integer n (n!) is the product of all positive integers less than or equal to n. The factorial of zero is defined as 1. This is useful for calculating binomial coefficients.

Thursday, November 19, 2009

The Regex & StringTokenizer Challenge!

Sometimes programming is difficult - You have to make large architectural decisions, with overreaching implications on maintainability, performance and security. Other times, programming is simply frustrating - Something 'simple' doesn't work the way you expected, you're seriously testing your logic and finally you bring out the paper and pen for some good-old pseudo code!

The problem...
I was doing some pro-bono processing work on an excel file, removing duplicate rows based on some complicated criteria. Preferring to keep my sanity I abandoned VBA so I exported the spreadsheet to CSV. The crunch is, some of the cells were blank and this produced unpredictable results in my code. Here's a sample of the data:


  1. ,,dsafdf,,15,,,,
  2. ,,fdsfjladsjf,,13,,,,
  3. df,,sdff,,bemail,1,1,,
  4. dsf,,sffdsf,,bsgemail,1,1,,
  5. token1,token2,token3,token4,token5,token6,token7,token8,token9


I've added the fifth row for demonstration of the number of tokens. In a row that is complete, we are expecting 9 tokens. Their position is important!

Source Code
I've included some source code showing 3 different approaches:

  1. import java.util.StringTokenizer;


  2. public class Processor {

  3. public static void main (String[] args) {

  4. final String _DELIM = ",";

  5. //An array of the strings
  6. String[] sourceStrings = {
  7. ",,dsafdf,,15,,,,",
  8. ",,fdsfjladsjf,,13,,,,",
  9. "df,,sdff,,bemail,1,1,,",
  10. "dsf,,sffdsf,,bsgemail,1,1,,",
  11. "token1,token2,token3,token4,token5,token6,token7,token8,token9"
  12. };

  13. System.out.println("Approach One: String.split()");
  14. for(String s: sourceStrings)
  15. {
  16. //do the processing on the strings using
  17. //the delimiter as a regular expression;
  18. String[] split = s.split(_DELIM);

  19. System.out.println("Number of tokens : " + split.length);
  20. }

  21. System.out.println("Approach Two: StringTokenizer");
  22. for(String s: sourceStrings)
  23. {
  24. StringTokenizer st = new StringTokenizer(s, _DELIM, false);

  25. System.out.println("Number of tokens : " + st.countTokens());
  26. }

  27. System.out.println("\r\nApproach Three: StringTokenizer returning delimiter - Take One");
  28. for(String s: sourceStrings)
  29. {

  30. StringTokenizer st = new StringTokenizer(s, _DELIM, true);

  31. System.out.println("Number of tokens : " + st.countTokens());
  32. }
  33. }
  34. }

Output
A listing of the output of the code above is shown below:

  1. Approach One: String.split()
  2. Number of tokens : 5
  3. Number of tokens : 5
  4. Number of tokens : 7
  5. Number of tokens : 7
  6. Number of tokens : 9

  7. Approach Two: StringTokenizer
  8. Number of tokens : 2
  9. Number of tokens : 2
  10. Number of tokens : 5
  11. Number of tokens : 5
  12. Number of tokens : 9

  13. Approach Three: StringTokenizer returning delimiter - Take One
  14. Number of tokens : 10
  15. Number of tokens : 10
  16. Number of tokens : 13
  17. Number of tokens : 13
  18. Number of tokens : 17


Approach One: String.split()
The first approach uses the String.split() method passing in the delimiter as a regular expression. As can be seen, this fails the test as we have ranges of 5-9 tokens. The correct answer should be 9.

Approach Two: StringTokenizer
The second approach uses the StringTokenizer to split up the strings. Again, we get unpredictable results. 2 tokens for the first two lines, as it picks only the items that are not the delimiter. The Correct answer here would be 9 and for the items that are null, we should get a null token.

Approach Three: StringTokenizer returning the delimiter
The third approach uses the StringTokenizer with a different constructor that also returns the delimiter. Again, lots of wrong results. The correct number of tokens should be 17 - 8 commas and 9 non comma items, preferrably null.

So there you have it, a rather simple task (I would have thought), but I did bang my head against the wall trying to find the right solution. If I ever get to be a teacher, this would be great for an exam! There's the challenge! I'll post the solution soon.


UPDATE!

  1. public class NonCollapsingStringTokenizer {  
  2.   
  3.     private String str;  
  4.     private String delim;  
  5.     private int currentPosition;  
  6.   
  7.     private NonCollapsingStringTokenizer() {  
  8.           
  9.     }  
  10.   
  11.     public NonCollapsingStringTokenizer(String str, String delimStr) {  
  12.         this.str = str;  
  13.         this.delim = delimStr;  
  14.     }  
  15.   
  16.     public String nextToken() {  
  17.         int nextDelimPosition = str.length();  
  18.         int delimPosition = str.indexOf(delim, currentPosition);  
  19.         if (delimPosition >= 0 && delimPosition < nextDelimPosition) {  
  20.             nextDelimPosition = delimPosition;  
  21.         }  
  22.         String token = str.substring(currentPosition, nextDelimPosition);  
  23.         currentPosition = nextDelimPosition + 1;  
  24.         return token;  
  25.     }  
  26.   
  27.     public boolean hasMoreTokens() {  
  28.         return (currentPosition < str.length());  
  29.     }  
  30.       
  31.     public int countTokens() {  
  32.         int count = 0;  
  33.           
  34.         NonCollapsingStringTokenizer clone = (NonCollapsingStringTokenizer) this.clone();  
  35.         while(clone.hasMoreTokens())  
  36.         {  
  37.             clone.nextToken();  
  38.             count++;  
  39.         }  
  40.           
  41.         return count;  
  42.     }  
  43.       
  44.     public Object clone() {  
  45.         NonCollapsingStringTokenizer copy = new NonCollapsingStringTokenizer();  
  46.         copy.str = str;  
  47.         copy.delim = delim;  
  48.         return currentPosition;  
  49.           
  50.     }  
  51. }  

The class above handles the challenge accordingly. This can be tested with the code below:

  1. public static void main(String[] args) {  
  2.         String s = ",,dsafdf,,15,,,,";  
  3.           
  4.         final String _DELIM = ",";  
  5.         //s = "token1,token2,token3,token4,token5,token6,token7,token8,token9";  
  6.         s = ",,sffdsf,,bsgemail,1,1,5,dsf";  
  7.                   
  8.         NonCollapsingStringTokenizer ncst = new NonCollapsingStringTokenizer(s, _DELIM);  
  9.         int x = 1;  
  10.         while(ncst.hasMoreTokens()) {  
  11.             String nextToken = ncst.nextToken();  
  12.               
  13.             System.out.println(Integer.toString(x++) + " " + nextToken);  
  14.         }  
  15.     }  

This produces the listing below:

  1. 1   
  2. 2   
  3. 3 sffdsf  
  4. 4   
  5. 5 bsgemail  
  6. 6 1  
  7. 7 1  
  8. 8 5  
  9. 9 dsf