Showing posts with label Snippet. Show all posts
Showing posts with label Snippet. Show all posts

Sunday, September 13, 2020

Orbital velocity and altitude calculations in C#

Just thought I'd share a C# snippet for calculating nominal orbital speed if you have the center mass and orbital radius. And to go the other way if you have the center mass and speed to get the nominal orbital radius.


public static class OrbitalCalculations
{
    public const double G = 0.0000000000667d;
    public static double NominalOrbitalSpeed(double centerMass, double orbitalRadius)
    {
        if (orbitalRadius.IsZero())
            return 0;
        return Math.Sqrt(G * centerMass / orbitalRadius);
    }
    public static double NominalOrbitalRadius(double centerMass, double speed)
    {
        if (speed.IsZero())
            return 0;
        return G * centerMass / (speed * speed);
    }
    public static bool IsZero(this double d, double tolerance = 0.0001)
    {
        return Math.Abs(d) < tolerance;
    }
}
If you want the math behind and more: 
Hope this helps someone out there! : )

Wednesday, September 26, 2018

The elegance of a F# WebRequest


Love the elegance of doing a WebRequest in F#

module WebLoader =
    open System.Net
    open System.IO

    let GetString (url:string) =
        let request = WebRequest.Create(url)
        use response = request.GetResponse()
        use stream = response.GetResponseStream()
        use reader = new StreamReader(stream)
        reader.ReadToEnd()

Especially the use keyword compared to the C# using { } blocks. Me like!

Thursday, December 7, 2017

Asserting floating point values in unit tests


Just a few methods to help out with unit testing, mainly for asserting floating point values (float, double) to be within a tolerance of the expected value

public static class Dessert
{
    public static void AreEqual(double expected, double actual, double tolerance)
    {
        Assert.IsTrue(expected.IsEqual(actual, tolerance),
            $"{Environment.NewLine}Dessert.AreEqual(double, double) failed. Expected:<{expected}>. Actual<{actual}>. Tolerance<{tolerance}>");
    }
        
    public static void AreEqual(float expected, float actual, float tolerance)
    {
        Assert.IsTrue(expected.IsEqual(actual, tolerance),
            $"{Environment.NewLine}Dessert.AreEqual(float, float) failed. Expected:<{expected}>. Actual<{actual}>. Tolerance<{tolerance}>");
    }
}

How to use:

Dessert.AreEqual(2700, weight, 0.000000000000001);

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Wednesday, November 15, 2017

Distances to human readable text in C#


Needed a function that converts a double to a human readable distance in my latest project, ended up writing the following function.
Input argument is in meters.
For values less than 1 meter, the result is given as centimeters.
For values up to 10 km, the values are given with one decimal.
Values up to one tenth of an Astronomical Unit are given as kilometers.
Values between one tenth of an Astronomical Unit and one tenth of a Parsec are given in Astronimical Units.
Values larger then one tenth of a Parsec are given in Parsecs.

Example output
Input
Output
0.533
53 cm
-1 -1 m
1 1 m
3,08568E+16 1.0 pc
3,08568E+17 10.0 pc
1,49598E+12 10.0 AU
1000 1.0 km
10000 10 km


The code for you to use as you please:
public const double AstronomicalUnit = 149597870700;
// https://en.wikipedia.org/wiki/Parsec
public static double Parsec { get; } = (648000 / Math.PI) * AstronomicalUnit;
public static string ToReadableDistanceFavorParsec(double meters, CultureInfo cultureInfo = null)
{
    if (cultureInfo == null)
        cultureInfo = CultureInfo.InvariantCulture;
    var sign = meters.Sign() > 0 ? string.Empty : "-";
    meters = meters.Abs();
    if (meters > (Parsec / 10))
    {
        return $"{sign}{(meters / Parsec).ToString("0.0", cultureInfo)} pc";
    }

    if (meters > (AstronomicalUnit / 10))
    {
        return $"{sign}{(meters / AstronomicalUnit).ToString("0.0", cultureInfo)} AU";
    }

    if (meters > (997))
    {

        if (meters >= (10000))
        {
            return $"{sign}{(meters / 1000).ToString("0", cultureInfo)} km";
        }
        return $"{sign}{(meters / 1000).ToString("0.0", cultureInfo)} km";
    }

    if (meters < 1)
    {
        return $"{sign}{meters * 100:0} cm";
    }
    return sign + meters.ToString("0") + " m";
}


All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Friday, November 11, 2016

PictureBox SafeReplaceImage extension


Another extension for the winforms picturebox component.
Basically it just lets you forget about the disposal of the previous image. Saved me a lot of headache.

Some source-code (C#)
public static void SafeReplaceImage(this PictureBox pbox, Image image)
{
 var tmp = pbox.Image;
 pbox.Image = image;
 if (tmp != null)
 {
  tmp.Dispose();
  tmp = null;
 }
}

Hope this helps someone out there! :)

Back to extensions list


Monday, November 7, 2016

Extension PictureBox ResizeImageToFit


Another useful extension, this time for the standard Windows Forms PictureBox. The issue for me, is that I usually just want to throw a picture at it and it should just show it, not crop it, not kill the aspect ratio etc. So I tend to use this extension method after assigning a new picture to the PictureBox.Image property to correctly show the picture in center mode if it is smaller then the box, or zoom it to fit inside the box if it is larger, still keeping the aspect ratio.

Some source-code (C#)
public static void ResizeImageToFit(this PictureBox pbox)
{
 if (pbox.Size.Height > pbox.Image.Size.Height && pbox.Size.Width > pbox.Image.Size.Width)
  pbox.SizeMode = PictureBoxSizeMode.CenterImage;
 else
  pbox.SizeMode = PictureBoxSizeMode.Zoom;
}

Hope this helps someone out there :)

Back to extensions list


Friday, November 4, 2016

String extension for Contains, with StringComparison

So, many of the built in string methods have the possibility to set the StringComparison in code, to for example OrdinalIgnoreCase wich is my favorite for most back-end processing.
Sad thing is, the Contains does not have it. So here is a small extension that fixes it with the help of IndexOf method

Some source-code (C#) to copy into your utilities class.

public static bool Contains(this string s, string sub, StringComparison comparison)
{
    return s.IndexOf(sub, comparison) != -1;
}

Hope this helps someone out there :)

Back to extensions list

Saturday, October 8, 2016

WinForms RichTextBox Append Log and UIThread extensions

Turn any RichTextBox in winforms to a log view. Just call rtxt.AppendLog("someString"); and it will append that to a new line in the richtextbox. And scroll it to view.

public static void AppendLog(this RichTextBox rtxt, string s)
{
 rtxt.UIThread(() =>
 {
  rtxt.AppendText($"{s}{Environment.NewLine}");
  rtxt.SelectionLength = 0;
  if (rtxt.Lines.Length > 10000)
  {
   rtxt.Lines = rtxt.Lines.Skip(5000).ToArray();
  }
  rtxt.SelectionStart = rtxt.TextLength;
  rtxt.ScrollToCaret();
 });
}
The above snippet of code requires the following to function correctly.
static public void UIThread(this Control control, Action code)
{
 if (control.InvokeRequired)
 {
  control.BeginInvoke(code);
  return;
 }
 code.Invoke();
}
I can't take credit, found it years ago on some forum somewhere. But here it is anyway. It makes a call to a winforms control synschronize with the GUI thread so that no cross-threading exceptions is thrown. GUI items can only be modified from the GUI thread and this ensures just that.

The exception thrown if correct thread synchronization is not used is: 
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cross-thread operation not valid: Control 'rtxtOutput' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.TextBoxBase.GetSelectionStartAndLength(Int32& start, Int32& length)
       at System.Windows.Forms.TextBoxBase.set_SelectionLength(Int32 value)
       at System.Windows.Forms.RichTextBox.set_SelectionLength(Int32 value)
       at ave.dev.winform.Form1.ticker_Tick(Object sender, EventArgs e) in C:\tfs\YYY\Form1.cs:line 54
       at ave.dev.winform.Form1._loggerHook_NewLogLine(String s) in C:\tfs\YYY\Form1.cs:line 38


Back to extensions list

Friday, October 7, 2016

Transform string to and from camel case.

Small piece of code to transform a string to and from camel case form. For anyone who find that kind of things useful.

private static readonly char[] Delimeters = {' '}; 
public static string ToCamelCase(string input)
{
 var sb = new StringBuilder();
 input = input.ToLowerInvariant();
 var split = input.Split(Delimeters, StringSplitOptions.RemoveEmptyEntries);
 foreach (var s in split)
 {
  for(int i = 0; i < s.Length; i++)
  {
   var c = s[i];
   sb.Append(i == 0 ? char.ToUpperInvariant(c) : c);
  }
 }
 return sb.ToString().Trim();
}

public static string FromCamelCaseToNormal(string input)
{
 var sb = new StringBuilder();
 foreach (var c in input)
 {
  if (char.IsUpper(c) 
   || char.IsDigit(c))
   sb.Append(" ");
  sb.Append(c);
 }
 return sb.ToString().Trim();
}

Saturday, October 1, 2016

Get random item from a list extension


private static Random _random = new Random();
public static T GetRandom<T>(this List<T> list)
{
    if (list.Count == 0)
        return default(T);
    if (list.Count == 1)
        return list[0];
    return list[_random.Next(0, list.Count)];
}

Very useful in a broad range of scenarios when you want to get a random element from a list.
Just call myList.GetRandom()

Back to extensions list


Wednesday, September 21, 2016

String to Enum parsing


The normal way of parsing an string containing an enum value:

var text = "Unknown";
var parsed = (KnownType)Enum.Parse(typeof(KnownType), text, true);

I've always found this to be ugly when scattered in the code base and usually I solve it by adding the following string extension to the projects utility class:

public static <T> ParseEnum(this string s)
{
    return (T) Enum.Parse(typeof (T), s, true);
}

Usage:

var text = "Unknown";
var parsed = text.ParseEnum<KnownType>();


Hope this helps someone out there

Saturday, April 13, 2013

C# array compress and decompress with GZipStream

A small utility class for compressing and decompressing using the GZip algorithm that is built into the .NET framework class GZipStream.
The GZipStream class works with streams, so we need to create a stream to be able to use it. I.e. the GZipStream will write to a stream and also read from a stream.

Compress

For the Compress function we will create a MemoryStream and wrapping it with a using statement so that it is correctly disposed when it leaves scope. We nest a creation of a GZipStream and pass it our MemoryStream and set the compression level to optimal.
Available compression levels are

  • Optimal. Can take a little longer, but will compress the data as best as it can
  • Fastest. Will do a fast compression, the data might not be compressed fully, but sometimes this is good enough.
  • NoCompression. Will not compress, just encode it as a gzip
Then it is just to write the byte array to the GZipStream and call the ToArray() function on the MemoryStream to receive the underlying byte array that can be used.


public static class Compression
{
    public static byte[] Compress(byte[] data)
    {
        using (var ms = new MemoryStream())
        {
            using (var gzip = new GZipStream(ms, CompressionLevel.Optimal))
            {
                gzip.Write(data, 0, data.Length);
            }
            data = ms.ToArray();
        }
        return data;
    }
    public static byte[] Decompress(byte[] data)
    {
        // the trick is to read the last 4 bytes to get the length
        // gzip appends this to the array when compressing
        var lengthBuffer = new byte[4];
        Array.Copy(data, data.Length - 4, lengthBuffer, 0, 4);
        int uncompressedSize = BitConverter.ToInt32(lengthBuffer, 0);
        var buffer = new byte[uncompressedSize];
        using (var ms = new MemoryStream(data))
        {
            using (var gzip = new GZipStream(ms, CompressionMode.Decompress))
            {
                gzip.Read(buffer, 0, uncompressedSize);
            }
        }
        return buffer;
    }
}

Decompress

For the decompress part we will start with figuring out the length of the uncompressed size by reading the first four bytes of the input array and converting those to a integer.
After that we create our resulting output byte array to the uncompressed size.
And then again with the MemoryStream and GZipStream, this time we send in the Decompress enum member to specify that we want to decompress the stream.
Note that we call the MemoryStream constructor with the input byte array and that we use the GZipStream to read to the resulting buffer from position 0 to the uncompressed size of the data.

Hope this helps someone out there!


Tuesday, October 11, 2011

Thread Pooling work items in C#

Sometimes you want to perform a work item in another thread but not go through the hassle to create a new thread. A good way to solve the problem is to use the ThreadPool.
using System.Threading;
 
namespace dsc.tools
{
    public class ThreadPooling
    {
        public void StartWorkItem()
        {
            ThreadPool.QueueUserWorkItem(context =>
            {
                // do stuff here
            });
            // or
            ThreadPool.QueueUserWorkItem(DoWork);
        }
 
        private void DoWork(object context)
        {
            // do stuff here
        }
    }
}

Monday, June 13, 2011

MongoDB C# Driver, Querying multiple fields with intervals

Simple way of chaining together a query when looking for records that require both field one and field two to be in a certain interval.
double foo = 1.0;
double bar = 2.0;
MongoCollection<BsonDocument> items = db.GetCollection<BsonDocument>("collection");
var query = Query.And(
    (Query.GT("field_one", foo).LT(bar)),
    (Query.GT("field_two", foo).LT(bar))
    );
MongoCursor<BsonDocument> dbResult = items.Find(query)
    .SetLimit(count);

Thursday, June 9, 2011

MongoDB C# Driver, Query multiple tags that are required

Tried hard to find the solution to querying multiple tags through the MongoDB C# driver.
Many of the solutions that I found were about using OR to put together the tags but I needed to AND the tags. I.e. all tags supplied were required to be present on in the result.
The solution was quite simple actually. Just my mind that thought it would require some special solution.
string[] tags = new string[] {"foo", "bar"};
var sort = SortBy.Descending("created");
var query = MongoDB.Driver.Builders.Query.All("tags", BsonArray.Create(tags));
var dbPages = pages.Find(query)
.SetSortOrder(sort)
.SetLimit(limit)
.SetSkip(offset);

  1. Create a string array with the tags that you want to query with
  2. Add sorting if needed
  3. Call MongoDB.Driver.Builders.Query to build your query
  4. Use find on your MongoCollection together with your query.
  5. Add Limit and Offset if needed.
Enjoy : )

Tuesday, October 12, 2010

WPF Dispatcher

guiControl.Dispatcher.Invoke(
    System.Windows.Threading.DispatcherPriority.Normal,
    Action(() =>
    {
        // do stuff
    }));
Ensure that GUI control manipulation is done in the GUI thread.

ThreadStart snippet


using System.Threading;
Thread thread = new Thread(
 new ThreadStart(() =>
  {
   // do stuff
  }));
thread.Start();
Snippet for creating separate thread inline and starting it.