Batch files to your PATH to access two executables with the same name without the full file path

I use both Python 2.7 and Python 3.3 frequently from the Windows Command Prompt. If I would only use one version, I’d add the folder containing the executable to my PATH environment variable so I did not always have to type out the full path, but only python. However, because there are two folders with a python.exe executable, adding both folders to the PATH wouldn’t be useful: only one of the two executables would be called when executing python, and for the other one, I’d still have to type out the full path.

That’s why I went to look for a solution to be able to call Python 2.7 by executing the command python2, and Python 3.3 by executing the command python3, without renaming the executables to python2.exe and python3.exe — I wanted to keep their original file names. The solution in this post can be applied to any similar situation, I just take Python as example here.

The first step is to create a folder at any location. In this folder, create two new files: python2.bat and python3.bat. These files will contain the commands to call the right Python version.

My python2.bat contains this:

@echo off
C:\Python27\python %*

@echo off makes sure that commands executed later are not displayed on the screen. Their output still is, but the command itself is not. If you remove that line, you’ll see this line printed when executing the file:

C:\your_folder_path>C:\Python27\python

C:\Python27\python %* executes Python 2.7. %* holds the arguments given to the Batch file, and these get passed to Python.

python3.bat looks very similar, only Python27 is replaced with Python33.

Now, we have our Batch files. But we are not ready yet. Now you’d have to use the full file path to these Batch files to execute them, and the goal was to be able to call python2 and python3 without having to enter a full path. To do this, you have to add the folder containing the Batch files to your PATH. Go to Control Panel > System and Security > System and you’ll see an “Advanced System Settings” link. Click on this one, go to the “Advanced” tab, click “Environment Variables”, select “Path”, and add your Batch folder there. Make sure it’s separated from the previous folder by a semicolon.

And now, you can call python2 and python3 without having to write a full file path!

Python and Global Variables

Recently I was writing some Python code, and I used a global variable whose value was set in a method. Here is a simple piece of code to demonstrate this:

list_with_data = []

def load_data_into_list():
    list_with_data = [1, 2, 3] # the actual code loaded data from a file, this is just to demonstrate what the code does

load_data_into_list()

When running the code, it didn’t work because the list was still empty after calling the load_data_into_list() function, but I didn’t notice that until I stored the list (with some new data) into the same file. Then I saw that the previous data was wiped and only the new data remained. So I did some debugging and I found out that the list was still empty though I called the method. The reason was that I intended to load the data into the global list_with_data variable, but Python created another variable list_with_data, but only in the scope of the function. Fortunately, that could be easily solved:

list_with_data = []

def load_data_into_list():
    global list_with_data
    list_with_data = [1, 2, 3]

load_data_into_list()

The global keyword tells the interpreter that I want to use the global variable.

Now, if you have many global variables, it’s quite difficult to write a global ... statement for them all. And there were some more global variables in the code, so instead, I put them in a class, like this:

class GlobalVariables:
    list_with_data = []

def load_data_into_list():
    GlobalVariables.list_with_data = [1, 2, 3]

load_data_into_list()

With a class, you don’t have to use the global keyword anymore, which saves you from writing 10 (or more) lines only to tell the interpreter that you want to use a global variable.

Transposing the rows and columns of a 2D array, jagged array and string in C#

Download extension methods

About the download

The download is a ZIP file containing the C# file, in which you can find the extension methods.

Introduction

Sometimes, when you write a program, you might need to transpose the rows and columns of a 2D array, a jagged array (an array of arrays) or a string. In this blog post, I’ll explain you how to do that.

The methods I’ll show you in this blog post are extension methods[^]. Put these in a static class (for example,TransposeRowsColumnsExtension), and then you can call them like yourArray.TransposeRowsAndColumns(); If you don’t use .NET 3.5 or later, you cannot use extension methods. Then, just remove the this keyword from the parameter list and you can call the methods like TransposeRowsColumnsExtension.TransposeRowsAndColumns(yourArray);
Note that the methods don’t change the original array! If you want to adjust the original array, use yourArray = yourArray.TransposeRowsAndColumns();

Transposing rows and columns of a 2-dimensional array

The first thing we do here is to create a new array. The height of the new array will be the width of the original array, and the width of the new array will be the height of the original array. Then, we run a loop and fill the new array with elements. And when doing this, the columns of the original array become the rows of the new array and vice versa. But it it’s a square, we can make it a lot faster (thanks to CatchExAs for the suggestion!), by cloning the array and swapping the items inside the array itself by iterating over the half of the array, from the upper-left to the bottom-right corner, excluding the items at the diagonal, and then perform the swap. When it’s a square, we start the outer loop from 1 (not from 0, because [0, 0] is on the diagonal) and the inner loop starts at 0 and runs while j (the variable of the inner loop) is less than i (the variable of the outer loop).

public static T[,] TransposeRowsAndColumns<T>(this T[,] arr)
{
    int rowCount = arr.GetLength(0);
    int columnCount = arr.GetLength(1);
    T[,] transposed = new T[columnCount, rowCount];
    if (rowCount == columnCount)
    {
        transposed = (T[,])arr.Clone();
        for (int i = 1; i < rowCount; i++)
        {
            for (int j = 0; j < i; j++)
            {
                T temp = transposed[i, j];
                transposed[i, j] = transposed[j, i];
                transposed[j, i] = temp;
            }
        }
    }
    else
    {
        for (int column = 0; column < columnCount; column++)
        {
            for (int row = 0; row < rowCount; row++)
            {
                transposed[column, row] = arr[row, column];
            }
        }
    }
    return transposed;
}

Transposing rows and columns of a jagged array

It’s basically the same story for a jagged array (an array of arrays). But here, we cannot immediately specify the size of the arrays inside the new jagged array. So, first, we fill the new jagged array with N arrays that consist of M items. Here, N is equal to the count of columns of the original jagged array (and those columns become rows in our new jagged array), and M is equal to the count of rows in the original jagged array. For this, we don’t need an extra loop, we can just create the inner arrays in our first loop. Note: if the inner arrays of the original array don’t have an equal count of items, this method might not work properly or throw an exception.

public static T[][] TransposeRowsAndColumns<t>(this T[][] arr)
{
    int rowCount = arr.Length;
    int columnCount = arr[0].Length;
    T[][] transposed = new T[columnCount][];
    if (rowCount == columnCount)
    {
        transposed = (T[][])arr.Clone();
        for (int i = 1; i &lt; rowCount; i++)
        {
            for (int j = 0; j &lt; i; j++)
            {
                T temp = transposed[i][j];
                transposed[i][j] = transposed[j][i];
                transposed[j][i] = temp;
            }
        }
    }
    else
    {
        for (int column = 0; column &lt; columnCount; column++)
        {
            transposed[column] = new T[rowCount];
            for (int row = 0; row &lt; rowCount; row++)
            {
                transposed[column][row] = arr[row][column];
            }
        }
    }
    return transposed;
}

Transposing rows and columns of a string

Here, we have three arguments instead of one: the string, the row delimiter and the column delimiter. First, we split the string by the row delimiter (this returns an array of rows), and then we split each row by the column delimiter, to get a jagged array. After doing that, we call the TransposeRowsAndColumns method and pass the jagged array as argument. And finally, we convert the transposed jagged array back to a string.

public static string TransposeRowsAndColumns(this string str, string rowDelimiter, string columnDelimiter)
{
    string[] rows = str.Split(new string[] { rowDelimiter }, StringSplitOptions.None);
    string[][] arr = new string[rows.Length][];
    for (int i = 0; i &lt; rows.Length; i++)
    {
        arr[i] = rows[i].Split(new string[] { columnDelimiter }, StringSplitOptions.None);
    }
    string[][] transposed = TransposeRowsAndColumns(arr);
    string[] transposedRows = new string[transposed.Length];
    for (int i = 0; i &lt; transposed.Length; i++)
    {
        transposedRows[i] = String.Join(columnDelimiter, transposed[i]);
    }
    return String.Join(rowDelimiter, transposedRows);
}

Examples of usage

These examples of usage are made for .NET 3.5 and later, because these methods are extension methods. If you use a version before .NET 3.5, use YourClass.TransposeRowsAndColumns(arr) instead of arr.TransposeRowsAndColumns()

Two-dimensional array

// Example 1:
int[,] twoDimensional = { 
                            { 1, 2, 3, 4 },
                            { 1, 2, 3, 4 },
                            { 1, 2, 3, 4 }
                        };
twoDimensional = twoDimensional.TransposeRowsAndColumns();
/* Result
{
{ 1, 1, 1 },
{ 2, 2, 2 },
{ 3, 3, 3 },
{ 4, 4, 4 }
}
*/
// Example 2:
int[,] twoDimensional1 = { 
                            { 1, 2, 3, 4 },
                            { 5, 6, 7, 8 },
                            { 9, 10, 11, 12 },
                            { 13, 14, 15, 16 }
                        };
twoDimensional1 = twoDimensional1.TransposeRowsAndColumns();
/* Result:
{
  { 1, 5, 9, 13 },
  { 2, 6, 10, 14 },
  { 3, 7, 11, 15 },
  { 4, 8, 12, 16 }
}
*/

Jagged array

int[][] jagged = {
                     new int[] { 1, 2, 3, 4 },
                     new int[] { 1, 2, 3, 4 },
                     new int[] { 1, 2, 3, 4 }
                 };
jagged = jagged.TransposeRowsAndColumns();
// Result: same as for 2D array, but as a jagged array

String

// Example 1:
string str = "1 2 3 4;1 2 3 4;1 2 3 4";
str = str.TransposeRowsAndColumns(";", " ");
// Result: "1 1 1;2 2 2;3 3 3;4 4 4"
// Example 2:
string str1 =
@"1 2 3 4
1 2 3 4
1 2 3 4";
str1 = str1.TransposeRowsAndColumns(Environment.NewLine, " ");
/* Result:
@"1 1 1
2 2 2
3 3 3
4 4 4"
*/
// Example 3:
string str2 = 
@"1,2,3,4
5,6,7,8
9,10,11,12
13,14,15,16";
str2 = str2.TransposeRowsAndColumns(Environment.Newline, " ");
/* Result:
@"1,5,9,13
2,6,10,14
3,7,11,15
4,8,12,16"
*/

Why IP Bans Are Not Always a Good Idea


Some websites ban specific IP addresses to block users with intolerable behaviour. But these bans are not always a good idea. Why not? Because changing your IP address is very easy: just turn off your router and turn it on again, and your IP is changed (if you have a dynamic IP and not a static one). But even if you have a static IP, changing it into a dynamic IP is very easy. So banning an IP is not very effective, and, even worse, it can also block an innocent user if the banned IP is assigned unforeseen to that user.

But can IP bans be effective? Yes, they can, if you want to ban an anonymous open proxy, because their IP addresses don’t change that much. It can also be effective if you want to ban someone for a short time, for example if someone is continuously sending requests to your website. You don’t disturb other users with the same IP too much (at least if you tell the reason), and you prevent the attacker from sending more requests.

But I want to block a user permanently! How can I do that?
Well, in fact, you cannot really prevent someone from accessing your website. The best you can do is using a user account system, and block the email address of annoying users. It doesn’t really stop them because they can keep creating new email addresses, but it’s better than nothing. Also, when doing that, make sure that you confirm the email address before the account is created. Otherwise, someone can use a non-existing email address and it won’t change anything if that email address gets banned.