Use LINQ with an embedded lambda expression to find prime numbers in C# (Part 3 of 3)

[prime numbers]

The example Use more efficient LINQ to find prime numbers in C# (Part 2 of 3) uses a LINQ query to find prime numbers. It creates a delegate variable named IsOddPrime referring to a lambda expression and uses it to determine whether a number is prime and should therefore be selected.

It occurred to me that you should be able to use a lambda expression directly in the LINQ query without assigning it to a delegate variable. Unfortunately, I couldn’t find any examples. All of the examples I found created a query without a where clause and then called the query’s Where method passing it a lambda expression. After some trial and error, I found that the following query works.

var primes =
    from number in Enumerable.Range(1, max / 2)
    where (
        (Func<int, bool>)(n =>
            {
                for (int i = 3; i * i <= n; i += 2)
                    if (n % i == 0) return false;
                return true;
            }
        )
    )(2 * number + 1)
    select 2 * number + 1;

The lambda expression is shown in blue.

The code casts the lambda expression into a Func<int, bool>, a function that takes an int as a parameter and returns a bool result. The cast operator is shown in green.

The code wraps the result in parentheses to ensure that the cast operator is applied. It then invokes the method passing it the value 2 * number + 1.

I think the previous version is easier to understand and the two should have the same performance. This version is basically an exercise in figuring out how to use an embedded lambda expression in a LINQ query. See the previous example for more details on how the rest of the program works.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, LINQ, mathematics | Tagged , , , , , , , , , , | 4 Comments

Use more efficient LINQ to find prime numbers in C# (Part 2 of 3)

[prime numbers]

The previous post showed how you can use LINQ to find prime numbers. For every number between 1 and a maximum, the LINQ query called the IsPrime method to see if the number should be part of the selection.

That works, but it’s pretty inefficient because half of the numbers it examines are even. That means roughly half of the calls to IsPrime are wasted work.

This example uses the following code to check only the odd numbers between 1 and the maximum. It also uses a lambda expression instead of a separate IsPrime method.

// Find primes.
private void btnGo_Click(object sender, EventArgs e)
{
    int max = int.Parse(txtMax.Text);

    // Define the IsOddPrime delegate.
    Func<int, bool> IsOddPrime = n =>
    {
        for (int i = 3; i * i <= n; i += 2)
            if (n % i == 0) return false;
        return true;
    };

    // Check odd numbers.
    var primes =
        from number in Enumerable.Range(1, max / 2)
        where IsOddPrime(2 * number + 1)
        select 2 * number + 1;

    // Add the number 2.
    List<int> numbers = primes.ToList();
    numbers.Insert(0, 2);

    // Remove max + 1 if it is in the list.
    if (numbers[numbers.Count - 1] > max)
        numbers.RemoveAt(numbers.Count - 1);

    // Display the results.
    lstPrimes.DataSource = numbers;
}

The code gets the maximum value you entered as in the previous example. It then defines the delegate variable IsOddPrime. It sets this variable equal to a statement lambda that determines whether an odd number greater than 1 is prime. Because it assumes the number is odd and greater than 1, it skips test that the previous version of the program had to make.

The statement lambda considers odd values i starting at 3. As long as i squared is less than or equal to the number in question, then i might be a factor of the number. If i divides the number evenly, then i is a factor so the number is not prime and the method returns false.

If none of the values of i evenly divide the number, then the lambda returns true.

Having initialized the IsOddPrime variable, the code uses it in a LINQ query. This time the query loops over a range that starts at 1 and contains max / 2 values. For each value i, the query examines 2 * i + 1. As i covers the range, 2 * i + 1 covers odd values between 3 and max + 1. The query uses IsOddPrime to see if 2 * i + 1 is prime and, if it is, selects it.

This query has two problems. First, it doesn’t include 2 as a prime. To solve that problem, the program adds 2 at the beginning of the result list.

The second problem is that the loop considers the value max + 1. If that result happens to be a prime, it gets added to the list even though it is greater than max. You can either ignore this or remove that value as shown in the code above.

The code finishes by displaying the prime numbers.

This code runs much faster than the previous version because it considers roughly half as many numbers as candidate primes. In practice you won’t notice much difference unless you are selecting a lot of primes. Perhaps up to 10 million or so.

In my next post, I’ll show how to make this query more LINQ-like. (Although the version shown here may be the best because it’s just as fast and easier to understand.)


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, LINQ, mathematics | Tagged , , , , , , , , , , | 1 Comment

Use LINQ to find prime numbers in C# (Part 1 of 3)

[prime numbers]

This example uses LINQ to find prime numbers between 1 and a maximum value that you enter. It defines the following IsPrime method to determine whether a number is prime.


// Return true if the number is prime.
private bool IsPrime(int number)
{
    if (number < 2) return false;
    if (number == 2) return true;
    if (number % 2 == 0) return false;
    for (int i = 3; i * i <= number; i += 2)
        if (number % i == 0) return false;
    return true;
}

If the number is less than 2, then the number is not prime so the method returns false.

If the number equals 2, then the number is prime so the method returns true.

If the number is evenly divisible by 2, then the number is even (and not 2) so it is not prime and the method returns false.

Finally, to handle the more interesting case, the program considers odd values i starting at 3. As long as i squared is less than or equal to number, then i might be a factor of number. If i divides number evenly, then i is a factor so number is not prime and the method returns false.

If none of the odd i values divides number evenly, then number is prime and the method returns true.

Now the program can use the IsPrime method to find prime numbers. When you click the Go button, the following code executes.

// Find primes.
private void btnGo_Click(object sender, EventArgs e)
{
    int max = int.Parse(txtMax.Text);

    // Examine numbers to find primes.
    var primes =
        from number in Enumerable.Range(1, max)
        where IsPrime(number)
        select number;

    // Display the results.
    lstPrimes.DataSource = primes.ToList();
}

First, the code gets max, the maximum number that you want to consider. It then defines a LINQ query.

The query examines numbers chosen from Enumerable.Range(1, max). The Enumerable.Range method generates a sequence of numbers starting at an intitial value (1 in this example) and containing a given number of values (this example’s range contains max values).

The query’s where clause picks the values for which the IsPrime method returns true. The select clause selects the values that pass the where clause’s filter.

The result is a query that returns an IEnumerable containing the prime numbers between 1 and max. The program calls the query’s ToList method to copy the results into a List and displays the results in the program’s ListBox.

This example is relatively straightforward, but it’s not terribly efficient, largely because the LINQ query considers lots of even numbers that you know are not prime. In my next post I’ll show how to make this query more efficient.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, LINQ, mathematics | Tagged , , , , , , , , , | 1 Comment

Draw a cursor and use it at run time in C#

[draw a cursor]

It’s not too hard to draw a cursor and use it in a C# program. The basic approach is to create a Bitmap and then create a new Cursor object, passing its constructor the Bitmap object’s icon handle as given by its GetHicon method.

When the example starts, it uses the following code to draw a cursor that displays two diamonds. The inner diamond is opaque and the outer diamond is translucent. (If you look closely at the picture, you’ll see the background image showing through the outer diamond.)


private void Form1_Load(object sender, EventArgs e)
{
    // Fit the background image.
    this.ClientSize = this.BackgroundImage.Size;

    // Draw the cursor image.
    const int wid = 63;
    const int hgt = 63;
    Bitmap bm = new Bitmap(wid, hgt);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.Clear(Color.Transparent);

        int cx = wid / 2;
        int cy = hgt / 2;
        Point[] outer_points =
        {
            new Point(cx, 0),
            new Point(2 * cx, cy),
            new Point(cx, 2 * cy),
            new Point(0, cy),
        };
        using (SolidBrush br =
            new SolidBrush(Color.FromArgb(128, 255, 255, 0)))
        {
            gr.FillPolygon(br, outer_points);
        }
        gr.DrawPolygon(Pens.Red, outer_points);

        Point[] inner_points =
        {
            new Point(cx, cy - 6),
            new Point(cx + 6, cy),
            new Point(cx, cy + 6),
            new Point(cx - 6, cy),
        };
        gr.FillPolygon(Brushes.LightBlue, inner_points);
        gr.DrawPolygon(Pens.Blue, inner_points);
    }

    // Turn the bitmap into a cursor.
    this.Cursor = new Cursor(bm.GetHicon());
}

The code defines constants to represent the cursor’s width and height. This example uses a 63 x 63 pixel cursor, but you can change those values to see what happens.

Next, the program creates a Bitmap of the desired size and a Graphics object to work with the Bitmap. It clears the Bitmap with the Transparent color so parts of the Bitmap that the program doesn’t draw on are invisible in the cursor.

The code then defines a large diamond. It fills the diamond with translucent yellow and then outlines the diamond in red.

Next, the code defines a smaller dialog, fills it with light blue, and outlines it in blue.

Finally, the program sets the form’s cursor to a new Cursor object created from the Bitmap. (That line is highlighted in blue.)


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , , , , , | Leave a comment

Let the user select the ScrollBar maximum in C#

[ScrollBar maximum]

You would think that allowing the user to select the ScrollBar maximum would be the default behavior. Unfortunately, that’s not the case.

The behavior of the VScrollBar and HScrollBar controls is largely determined by their Value, Minimum, Maximum, SmallChange, and LargeChange properties. Those properties have the following purposes.

  • Value – The control’s current value
  • Minimum – The smallest value that the control can have
  • Maximum – The smallest value that the control can have
  • SmallChange – The amount by which the value is changed when the user clicks one of the scroll bar’s arrows
  • LargeChange – The amount by which the value is changed when the user clicks between the “thumb” (the “slider”) and one of the scroll bar’s arrows

Suppose you create a scroll bar with the default property values: Minimum = 0, Maximum = 100, SmallChange = 1, and LargeChange = 10. That means the user can select any value between 0 and 100, right?

Wrong! The program can select any value between 0 and 100 but, in a dazzling example of what-were-they-thinking, Microsoft decided that the user should only be able to select values between 0 and 91.

More generally, the user can select values between the control’s Minimum value and Maximum - LargeChange + 1, which in this example is 100 – 10 + 1 = 91. Unless you set LargeChange = 1, which would be pretty inconvenient, the user cannot select the ScrollBar maximum.

If you want to let the user select values between min and max, set Minimum = min and set Maximum = max + LargeChange - 1. For example, if you want the user to be able to select values between 0 and 100 with the default LargeChange = 10, set Maximum = 100 + 10 - 1 = 109.

In the example program the lower scroll bar has Maximum set to 109 so the user can select values between 0 and 100.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in controls | Tagged , , , , , , , , , , , , , , , , | Leave a comment

Fix rectangle SmoothingMode problems in C#

[SmoothingMode]

This example explains how to fix a rather obscure SmoothingMode problem.

If you look closely at the PictureBox on the right in the picture, you’ll see that its top and leftmost pixels are not the same color as the rest of the control. The same thing was happening in a program I recently wrote and it took me quite a while to figure out.

This example uses the following code to display colored bitmaps on its two PictureBox controls. The difference between the pieces of code that create the bitmaps for the two controls solves “The Mystery of the Pink Pixels.”

private void Form1_Load(object sender, EventArgs e)
{
    int width, height;
    Bitmap bm;

    width = pictureBox1.ClientSize.Width;
    height = pictureBox1.ClientSize.Height;
    bm = new Bitmap(width, height);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.Clear(Color.Red);
        gr.FillRectangle(Brushes.White, 0, 0, width, height);
    }
    pictureBox1.Image = bm;

    width = pictureBox2.ClientSize.Width;
    height = pictureBox2.ClientSize.Height;
    bm = new Bitmap(width, height);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.SmoothingMode = SmoothingMode.AntiAlias;
        gr.Clear(Color.Red);
        gr.FillRectangle(Brushes.White, 0, 0, width, height);
    }
    pictureBox2.Image = bm;
}

The program gets the first PictureBox control’s client width and height and creates a Bitmap to fit it. It clears the Bitmap with red and then fills the control with a white rectangle that covers the Bitmap. When it has finished, the program displays the Bitmap in the first PictureBox.

Next, the program repeats those steps to make a Bitmap and display it in the second PictureBox. The only difference is that this time it sets the Graphics object’s SmoothingMode property to AntiAlias. That makes drawn shapes such as ellipses and lines look smoother. Unfortunately it also makes the FillRectangle method try to blend its edges into the background colors. Even though the rectangle goes all the way to the edge of the Bitmap, the FillRectangle method tries to blend its edge and that makes it pink instead of white. (It’s a bit odd that FillRectangle doesn’t do the same thing to the bottom and right edges of the rectangle.)

The moral of the story is: if you’re filling a rectangle and you don’t want its edges fuzzy, set SmoothingMode to None before you draw it.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , , | Leave a comment

Compress and decompress directories in C#

[compress and decompress directories]

The ZipFile class provides remarkably simple methods to compress and decompress directories in the zip format. This class is defined in the .NET Framework version 4.5, so this example is in Visual Studio 2017 instead of an older version.

To use the class, you need to add a reference to the System.IO.Compression.FileSystem library. This example also includes using directives for System.IO.Compression (where the class is) and System.IO (because the code uses the Path class).

When the program starts, the following code executes.

// Start with the source folder.
private void Form1_Load(object sender, EventArgs e)
{
    txtFolder.Text = Application.StartupPath;
    txtZipFile.Text = Path.GetFullPath(
        Path.Combine(Application.StartupPath,
            "..\\howto_zip_folder.zip"));
}

The first line makes the folder text box hold the path to the executable program’s folder. The second line makes the zip file text box hold the name howto_zip_folder.zip in the directory one level above the executable program’s directory.

When you click the Zip button, the following code executes.

// Zip the directory.
private void btnZip_Click(object sender, EventArgs e)
{
    try
    {
        ZipFile.CreateFromDirectory(txtFolder.Text,
            txtZipFile.Text);
        MessageBox.Show("Done");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The key is the call to the ZipFile class’s static CreateFromDirectory method. This method compresses the directory with name given by the first parameter and creates the zip file with name given by the second parameter. The rest of this code is error handling. For example, the code throws an exception of the zip file already exists.

When you click the Unzip button, the following code executes.

// Unzip the zip file.
private void btnUnzip_Click(object sender, EventArgs e)
{
    try
    {
        ZipFile.ExtractToDirectory(txtZipFile.Text,
            txtFolder.Text);
        MessageBox.Show("Done");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The key here is the call to the ZipFile class’s ExtractToDirectory method. Its parameters give the name of the zip file to decompress and the name of the directory where you want the results to land. As when compressing, most of this code is error handling.

Note that when you decompress, the directory where you want the results placed can exist, but the method will throw an exception if it tries to create a file that already exists.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in classes, directories, files | Tagged , , , , , , , , , , , , , , , , , , , | Leave a comment

Understand region directives in C#

[region directives]

Region directives let you define sections of code that you can collapse and expand by clicking the – and + signs to the left in the code window. Each region directive should have a corresponding endregion directive.

You can include optional text at the end of region directives to indicated which region is beginning or ending. If you include that text, then Visual Studio displays it when the region is collapsed.

Note, however, that Visual Studio doesn’t really do anything with after an endregion directive. Any text there is purely decorative and for your use only.

For example, suppose your program contains a long series of graphics methods. The following code shows how you might use region directives to make it easy to hide and show the graphics methods as a group.

...
#region Graphics Methods

private void DrawCircle(...)
{
    ...
}

private void DrawRectangle(...)
{
    ...
}

private void DrawHypotrochoid(...)
{
    ...
}

#endregion Graphics Methods

Now when you’re not working on the graphics methods, you can hide their region so they don’t clutter up the editor. (I often have code with all or most of the methods contained in a handful of regions so I only need to have the one I’m working on open at a given moment.)

You’ve probably seen region directives before. Even if you have, however, here are two region-related puzzles for you.

  1. What happens if your code includes regions that are not properly nested as in the following example?
private void Form1_Load(object sender, EventArgs e)
{
    int a = 1;
    #region "Region1"
    a++;
    #region "Region2"
    a++;
    #endregion "Region1"
    a++;
    #endregion "Region2"
    a++;
}
  1. What happens if a region lies partly inside and partly outside of a method as in the following example?
#region Region3

private void Test1()
{
    int b = 0;
    b++;
}

private void Test2()
{
    int b = 0;
    #endregion Region3
    b++;
}

You can easily try these out to see what happens so I won’t make this a puzzle to be solved in a later post. If you do want to think about it or try it out, do so now before reading the solutions that follow.


Okay, here are the answers.

  1. What happens if your code includes regions that are not properly nested as in the following example?

Visual Studio completely ignores the text after the region and endregion directives. It simply matches each endregion directive with the closest preceding region directive. That means the previous code is equivalent to the following.

private void Form1_Load(object sender, EventArgs e)
{
    int a = 1;
    #region Region1
    a++;
    #region Region2
    a++;
    #endregion Region2
    a++;
    #endregion Region1
    a++;
}

Even though Visual Studio ignores the strings after these directives, I recommend that you use them to make the code more readable.

  1. What happens if a region lies partly inside and partly outside of a method as in the following example?

I think this one is even more interesting. When you collapse a region that includes only part of a method, the region collapses the code up to the end of the method. This way you’re not left staring in confusion at half of a method.

The same is not true if the region starts inside a method and includes only part of a for loop or other block inside the method.

Finally, Visual Studio ignores a region if you start it inside a method and don’t end it in the same method. (I’m actually surprised it doesn’t just get confused and refuse to compile.)


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in coding, syntax | Tagged , , , , , , , , , , | 3 Comments

Disable Visual Studio warnings in C#


[Visual Studio warnings]

Visual Studio warnings let you know when your code contains something suspicious. For example, suppose you have XML documentation enabled.

To enable XML documentation, open the Project menu and select Properties. On the Build tab, check the XML Documentation File box and enter a file to hold the documentation. On the same tab, set the Warning Level to 4. (If that value is lower, Visual Studio does not display missing XML documentation warnings.)

If you enable XML documentation like this, Visual Studio warnings let you know if any public class members are missing XML documentation. The idea is that public members should have documentation to provide IntelliSense support. (And possibly text in documents that you may want to generate.) Visual Studio displays the following warning if the Form1 class defines a public method named Method3 without XML comments.

Missing XML comment for publicly visible type or member ‘howto_disable_warnings.Form1.Method3()’

The picture at the top of this post shows this error in the Error window.

However, sometimes Visual Studio warnings are unnecessary. For example, if you give a class a public method but don’t want to give it XML comments, you don’t really want to see the warning all the time.

In general, it’s not a good idea to leave Visual Studio warnings in the Error List. If the Error List is full of warnings that you want to ignore, the you won’t be able to see the ones you don’t want to ignore. Fortunately, you can use a pragma directive to remove specific Visual Studio warnings if you like.

First, you need to find out the warning number. In some versions of Visual Studio, you can find the number by digging through the Output window. In all versions (as far as I know), you can click on the warning in the Error List and then press F1.

You can also find a list of error and warning codes on the page C# Compiler Errors. Unfortunately, they’re listed by number not name.

Once you know the warning’s number, you can disable it and re-enable it as needed. The following code shows an example.

public partial class Form1 : Form
{
    /// <summary>
    /// Constructor.
    /// </summary>
    public Form1()
    {
        InitializeComponent();
    }

    /// <summary>
    /// This method does something that should
    /// be documented with an XML comment.
    /// </summary>
    public void Method1()
    {
    }

    // This method doesn't need XML documentation.
#pragma warning disable 1591
    public void Method2()
#pragma warning restore 1591
    {
    }

    // This method doesn't have XML documentation but should.
    public void Method3()
    {
    }
}

The code’s Form1 constructor and methods are public, so they all need XML comments. The code includes XML comments for the constructor and Method1.

The statement #pragma warning disable 1591 disables warning number 1591, which is the one you get if a method is missing an XML comment. When the compiler processes Method2, it doesn’t add this warning to the Error List.

The statement #pragma warning restore 1591 re-enables warning number 1591. When the compiler processes Method3, it displays this warning in the Error List.

Warnings are there for a reason, so you shouldn’t just disable every warning you see. Instead fix whatever it is that’s causing the warning. If you really can’t fix the issue and you know it won’t be a problem, then you can use pragma to disable the warning for a specific piece of code.

To avoid missing other warnings, only disable the warning for the smallest piece of code that makes sense.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in coding, syntax | Tagged , , , , , , , , , , , | Leave a comment

Use XML literals in C#


[XML literals]

Visual Basic lets you include XML literals directly in your code as in the following example.

Dim employees As XElement = 
    <employees>
      <employee firstname="Terry" lastname="Pratchett"/>
      <employee firstname="Glen" lastname="Cook"/>
      <employee firstname="Tom" lastname="Holt"/>
      <employee>
        <firstname>Rod</firstname>
        <lastname>Stephens</lastname>
      </employee>
    </employees>

Unfortunately, C# doesn’t allow XML literals. Fortunately, you can fake them fairly easily. Invoke the XElement class’s Parse method passing it the XML text as a string beginning with the @ character. Strings that begin with @ can span multiple lines so you can make these sorts of strings look a lot like XML literals.

The only restriction is that the string cannot contain any double quotes because then C# would think the string had ended. Usually in XML text you can use single quotes instead of double quotes. If you really need to use double quotes, you can double them up as in “”.

When the program starts, it executes the following code. The XML literal is shown in blue.

    private void Form1_Load(object sender, EventArgs e)
    {
        // Read the XElement.
        XElement xelement = XElement.Parse(
@"<employees>
    <employee firstname=""Terry"" lastname=""Pratchett""/>
    <employee firstname='Glen' lastname='Cook'/>
    <employee firstname='Tom' lastname='Holt'/>
    <employee>
      <firstname>Rod</firstname>
      <lastname>Stephens</lastname>
    </employee>
  </employees>
");

        // Display the nodes.
        foreach (XNode node in xelement.Nodes())
            lstNodes.Items.Add(node.ToString());
    }

The code creates an XElement variable and sets it equal to the result returned by the XElement.Parse method. It passes the method the XML literal. Notice that it uses doubled double quotes to delimit the values for Terry Pratchett.

After it loads the XML text, the program loops through the XElement object’s nodes and displays their text values in the program’s ListBox.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in strings, XML | Tagged , , , , , , , | Leave a comment