The Magical Mod Function

Tuesday Jan 1st 2008 by From ASP101
Share:

Mod is generally overlooked as a truly "useful" function in web programming. But, if you create shopping carts, online stores, photo albums, calendars, etc., anything that might need the flexibility of tables with variable numbers of items and/or items per row, it's a great tool to have under your belt.

by Steven J. Engelbrecht


Remember when you were in elementary school and had to do long division on paper? Before we learned about decimals and fractions we used to show the remainder as part of our answer. For instance, 22 / 7 = 3 R1. Remember?

Without even knowing it, we were mimicking a relatively obscure function in ASP called "mod", short for "modular division" or "modulo" in Latin. The "modulus", or remainder, is what is left over when we divide one number by another.

Syntax: number1 mod number2

For example, 22 mod 7 will yield an answer of 1. Likewise, 1 mod 7 will yield an answer of 1, as the answer is 0 with a remainder of 1.

Let's see it in action. Here's a simple script that will show the modulus of 1 through 10 divided by 5:


<%
For i = 1 to 10
    Response.write(i & " mod 5 = " & i mod 5 & "<br>")

Next
%>

This little script will give the following output:

1 mod 5 = 1
2 mod 5 = 2
3 mod 5 = 3
4 mod 5 = 4
5 mod 5 = 0
6 mod 5 = 1
7 mod 5 = 2
8 mod 5 = 3
9 mod 5 = 4
10 mod 5 = 0

Get it?

Many advanced encryption techniques, including the world-standard RSA Encryption Algorithm, use the mod function as part of their internal functioning. But surely there must be some useful applications of this little guy for the rest of us, right?

Well of course there are! Let's start with a fact that you may not have considered...

Any Positive Integer Mod 2 is Binary

Makes sense, right? Any positive integer when divided by 2 will have a remainder of either 0 or 1. Here's another little script to show off mod's mystical powers:


<%

For i = 1 to 10
    If i mod 2 = 1 Then
        Response.write(i & " is odd.<br>")
    Else

        Response.write(i & " is even.<br>")
    End If
Next
%>

Could this be useful to you? Maybe not like this, but here's the same idea in function form.


<%
Function isOdd(iInput)
    IsOdd = CBool( iInput Mod 2 )

End Function
%>

Not bad right? Now, we'll look at a truly useful application of the mod function: creating well-formed tables with a variable number of items to be displayed.

Recently I created a dynamic web-based photo album, and one of the views I wanted to add was a thumbnail display of all my images. Obviously I couldn't just loop through and display the images without a table, and it didn't make sense to show one thumbnail per row, so I was faced with an interesting challenge: how can I make sure the table is complete, i.e. has the same number of cells in every row, if I don't know how many items I'll be looping through?

Let me make sure you understand the problem before I explain the solution. Say we want a table with 3 cells in each row, and there are, for example, 9 items to be displayed. No problem, right? Three rows of three and we're done. But now suppose there are 10 items. Now, to keep the table well-formed (so it won't create any problems when viewed in unforgiving browsers), we have to create three rows of three, then an additional row with one cell containing the 10th item, then two empty cells and a close row tag. That's one problem. Now suppose we want to give the user the option of showing 3, 4, or 5 items per row. Obviously this wouldn't be fun to do by creating a bunch of nested if..thens or select cases. How can we manage this programatically?

Mod to the Rescue

To start, let's define a simple point that will permeate this example. If we want x items per row, and we have y items to be displayed, then if item_number mod x = 1 it will be the first item in the row, and if item_number mod x = 0 it will be the last item in the row (with item_number ranging from 1 to y). If item_number mod x is greater than 1, then it is an internal cell in the table and does not need an open row or close row tag next to it.

For example, here's how we could add 9 items to a table with 3 elements in each row:


<%
iCellsPerRow = 3
iItems = 9

' Create the table

strOutput = "<table>"

' Loop through all items
For i = 1 to iItems
    ' Check to see if this is the start of a new row
    If i mod iCellsPerRow = 1 Then strOutput = strOutput & "<tr>"

    ' Add a cell for this item
    strOutput = strOutput & "<td>" & i & "</td>"

    ' Check to see if this is the end of a row

    If i mod iCellsPerRow = 0 Then strOutput = strOutput & "</tr>"
Next

' Close the table

strOutput = strOutput & "</table>"

' Write the HTML output
Response.write(strOutput)
%>

Now if you're super observant, you may have noticed that this code won't work with a number of items that isn't evenly divisible by the number of cells per row. That's because we need one more clever piece of code to find out how many empty cells we have to add so that the last row matches up with the others. So now, after we've added all the elements to the table, we check first to see if we're at the end of a row, in which case we don't have to proceed, otherwise we create the rest of the row using empty cells.

The complete algorithm is as follows:


<%
iCellsPerRow = 3
iItems = 9

' Create the table
strOutput = "<table>"

' Loop through all items
For i = 1 to iItems
    ' Check to see if this is the start of a new row
    If i mod iCellsPerRow = 1 Then strOutput = strOutput & "<tr>"

    ' Add a cell for this item
    strOutput = strOutput & "<td>" & i & "</td>"

    ' Check to see if this is the end of a row

    If i mod iCellsPerRow = 0 Then strOutput = strOutput & "</tr>"
Next

' If we're not at the end of a row,
' fill the rest of the row with empty cells.

If iItems mod iCellsPerRow > 0 Then
    ' Loop through to complete table
    For j = 1 to iCellsPerRow - (iItems mod iCellsPerRow)
        ' Add an empty cell

        strOutput = strOutput & "<td>&nbsp;</td>"

        ' Add a close row tag if this is the last cell.
        If j = iCellsPerRow - (iItems mod iCellsPerRow) Then _
            strOutput = strOutput & "</tr>"

    Next
End if

' Close the table
strOutput = strOutput & "</table>"

' Write the HTML output
Response.write(strOutput)
%>

Conclusion

Unless you're in the cryptography business, mod is generally overlooked as a truly "useful" function in web programming. But, if you create shopping carts, online stores, photo albums, calendars, etc., anything that might need the flexibility of tables with variable numbers of items and/or items per row, it's a great tool to have under your belt.

The example I've created reads in two parameters: the number of cells per row, and the total number of items. It then runs some simple error checking on these inputted numbers, casts them as integers, then creates a table using the above described algorithm. For those of you that are interested, I also added the nice touch of calculating the width of the cells if you want them to be evenly spaced.

You can download the modtable.asp code in a zip file below..

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved