Category: .NET Core

Python vs C#

I have read the article https://www.red-gate.com/simple-talk/development/dotnet-development/10-reasons-python-better-than-c-sharp

I think that deserves an answer –  so I take all points to answer to them. You can replicate the code in C# 10 / .NET 6 with a globalusings.cs with the following content:


global using static System.Console;
global using static System.Linq.Enumerable;
global using static System.IO.Directory;
global using static System.String;
global using static System.Math;

So let’s start:

Point 1 - Indented code blocks

//Point 1 - Indented code blocks
//With curly braces I can indent whatever way I want - I am not constrained

using System.Collections.Generic;

foreach (var i in Range(1, 11))
{
if (i % 3 == 0)
WriteLine("fizz");
else if (i % 5 == 0)
WriteLine("buzz");

}

Also , when I want to comment something , with C# I know when the else if is
terminating without counting tabs. Just see where the { is closing with }

Point 2 -  Self-declaring Variables

Seriously? What is the difference between Python
//meaning_of_life = 42
and C# ? Just a var ?

//Point 2 - Self-declaring Variables
var meaning_of_life = 42;
Point 3 -– Those modules

It is the same code as Python

foreach (var file in EnumerateFiles(@"C:\")){
 WriteLine(file);
}
Point 4 – Simplicity of Data Structures

Quoting : Purists will say that you need all the different data types that C# provides, but trust me, you don’t.
I want to think about how to modelate a CallCenter waiting for phones – Stack or Queue ?
I want to think about how to  modelate a CallCenter waiting for phones with business consumer that has priority ?https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.priorityqueue

Point 5 - Slicing

Same code in C#

var sins = new[]{ "pride", "envy", "gluttony", "greed", "lust", "sloth", "wrath" };
//var selected_sins = sins[1..(sins.Length-1)];
var selected_sins = sins[1..^1];
WriteLine(Join(" ", selected_sins));
Point 6 – For loops

Same syntax in C#

foreach (var i in Range(0,5))
{
WriteLine(i);
}
// words in a string
string[] words = { "Simple", "Talk" };
foreach (string word in words)
{
WriteLine(word);
}

Quoting : “(unlike in C#, where sometimes you use for and sometimes foreach)”
Please enumerate an array backwards in python without reversing

7 – List comprehensions

This is similar code in C#

var nr = Range(1, 11).Where(it => it % 2 == 0).Select(it => Pow(it, 3));
WriteLine(Join(" ", nr));
8 – Sets

Same example

//this contains some duplicates
var languages = new[] { "C#", "Python", "VB", "Java", "C#", "Java", "C#" };
//more dense than Python
languages = new HashSet<string>(languages).ToArray();
//this will give: ['C#', 'Java', 'Python', 'VB']
WriteLine(Join(" ", languages));

Second example

//create two sets: Friends characters and large Antarctic ice shelves
var friends = new[] { "Rachel", "Phoebe", "Chandler", "Joey", "Monica", "Ross" };
var ice_shelves = new[] { "Ronnie-Filchner", "Ross", "McMurdo" };
// show the intersection (elements in both lists)
WriteLine(Join(" ", friends.Intersect(ice_shelves)));
//show the union (elements in either list)
WriteLine(Join(" ", friends.Union(ice_shelves)));
// show the friends who aren't ice shelves
WriteLine(Join(" ", friends.Except(ice_shelves)));
// elements in either set but not both -- more difficult
WriteLine(Join(" ", friends.Union(ice_shelves).Except(friends.Intersect(ice_shelves))));
9 – Working with files and folders
//# list of 3 people
var people = new[] { "Shadrach", "Meshach", "Abednego" };
//# write them to a file
File.WriteAllLines(@"C:\all\a.txt", people);
10 – The quality of online help

See https://docs.microsoft.com/ – good tutorials

FileExtension–part 6 – CI/CD

So now how to make visible all those coding ?

For tests –CodeCov,  https://app.codecov.io/gh/ignatandrei/FileExtension hosts for free to see the coverage

For documentation – ReadTheDocs,  https://fileextension.readthedocs.io/en/latest/ hosts for free.

For packaging  – NuGEt https://www.nuget.org/packages/FileExtension/

For more detailed analysis Sonar https://sonarcloud.io/summary/overall?id=ignatandrei_FileExtension can show code smells and bugs and more

GitHub actions https://github.com/ignatandrei/FileExtension/actions allows me to run all those automatically and gather results

For showing a website – Azure  – https://fileextension.azurewebsites.net/ can show the usage.

I was thinking that it is enough for the people to understand the application

FileExtension–Tests–part 5

The tests are the easy part. I have put some files on a folder( https://github.com/ignatandrei/FileExtension/tree/master/src/TestFileExtensions/TestFiles ) and test if the extension matches the recognizer.

As NuGet packages I used

FluentAssertions

xunit

LightBDD.XUnit2

FluentAssertion allows me to write more readable tests , like 

AllExtensions.Should().HaveCountGreaterThanOrEqualTo(number);

LightBDD allows me to write tests in a more “business “ way :

await Runner
     .AddSteps(Given_The_Recognizer)
     .AddAsyncSteps(_ => When_Read_The_File(fileName))
     .AddSteps(
         _ => Then_Should_Recognize_File(fileName),
         _ => Then_The_Extension_Matches(fileName)
     )
     .RunAsync();

You can see the result at https://fileextension.readthedocs.io/en/latest/BDD/LightBDDReport/ = go down to see the Given / When /

Also, for enumerating files from the folder to test, I use ClassData

[ClassData(typeof(DirectoryTestData))]
public async void TestMultipleFiles(string nameFile)

FileExtension – GUI–part 4

Now I must do something for the people that just want to use the software. The most usual , for me, it is a .NET Core WebAPI site ( with swagger ) and an Angular frontend.

You can find the sources at https://github.com/ignatandrei/FileExtension/tree/master/src . Some thoughts:

For .NET Core ( see https://github.com/ignatandrei/FileExtension/tree/master/src/RecognizeFileExtWebAPI ) I use the following NuGET packages ( other than usual .NET Core)

Microsoft.AspNetCore.Mvc.Versioning

Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

Swashbuckle.AspNetCore

Hellang.Middleware.ProblemDetails

AMSWebAPI

AMS_Base

RSCG_AMS

The final result can be seen at https://fileextension.azurewebsites.net/swagger

For Angular( https://github.com/ignatandrei/FileExtension/tree/master/src/FileExtensionAng) I use the following packages( other than usual Angular)

@angular/material

angular-shepherd

The final result can be seen at https://fileextension.azurewebsites.net/

FileExtension–plugins–part 3

What I have more in mind is that the people can add easy their code for extensions.

That means:

  1. Have an easy class to add the magic number in the header for an extension
  2. Have other people add their own implementations, not just the header
  3. Have an easy way to add the project with their code

 

First item it is easy – just create a class RecognizeFirstBytes and pass into constructor the first bytes

As an example , see the sln implementation


    public class RecognizeSln : RecognizeFirstBytes
    {
        public RecognizeSln() : base("EFBBBF0D0A4D6963726F736F66742056697375616C2053747564696F20536F6C7574696F6E2046696C65")
        {
            Extension = new string[1] { "sln" };
        }
    }

The second item can be implemented with an interface IRecognize


    public interface IRecognize: IEquatable<IRecognize>
    {
        Result InfoNeeded(byte[] b=null);
        string[] Extension { get; set; }
    }

The third item can be made by  making a third project  that  either references all other projects, either loading others as plugins . Because of the experience, I choose the most interesting one – plugins. I need first https://github.com/natemcmaster/DotNetCorePlugins . Second I need the plugins to be copied – I use a Target

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="xcopy &quot;$(ProjectDir)../plugins/*.dll&quot; &quot;$(ProjectDir)plugins&quot; /E /F /I /Y /R" />
  </Target>

And last I need this plugin loader , when packed as nuget  at https://www.nuget.org/packages/FileExtension/ , to have also the plugins – for this I use the csproj

<ItemGroup>
  <Content Include="plugins\**\*.dll">
    <PackagePath>build\net5.0\plugins\</PackagePath>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>

FileExtension– export data from CSV–part 2

First, is how to export data from table (https://en.wikipedia.org/wiki/List_of_file_signatures) into classes . First, the table must be transformed into a more programmatic recognizable way – like a CSV  – see https://github.com/ignatandrei/FileExtension/blob/master/src/RSCG_GCK/offset0.txt

Then a solution is to have into the dll ( as embedded resource or as a file) . The second solution, more complicated , is to use Roslyn Source Code Generators to generate the classes for each element of the CSV .

I’d liked more the second solution – the sources are at https://github.com/ignatandrei/FileExtension/tree/master/src/RSCG_GCK 

What it generates is like this

namespace RecognizeCustomSigs_GCK {
    class RecognizeFromGCKLine0_JP2: RecognizeFromLineCustomsigs{
        public RecognizeFromGCKLine0_JP2(): base("JPEG2000 image files,00 00 00 0C 6A 50 20 20,JP2")                
        {
        }
    }
}            

RSCG Example–TimeBombComment–part 27

 

 

name RSCG_TimeBombComment
nuget

https://www.nuget.org/packages/RSCG_TimeBombComment/

link http://msprogrammer.serviciipeweb.ro/category/roslyn/
author Andrei Ignat

This will generate an error from the comment after a certain date
 

The code that you start with is


    //TB: 2021-09-13 this is a comment transformed into an error

    //TB: and this is a warning

    //TB: 9999-12-30 and this will not appear

    Console.WriteLine("See the TB comment above ? ");


The code that you will use is



    //TB: yyyy-MM-dd this is a comment transformed into an error

 

The code that is generated is


    2>src\RSCG_TimeBombComment\Console_TimeBombComment\Program.cs(9,13,9,73): error TB: this is a comment transformed into an error

    2>src\RSCG_TimeBombComment\Console_TimeBombComment\Program.cs(10,13,10,40): warning TB: and this is a warning

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/TimeBombComment

All RSCG

NrBlog Post
1RSCG–part 1
2RSCG- AppVersion–part 2
3http://msprogrammer.serviciipeweb.ro/2021/02/17/rsgc-enum-part-3/
4RSGC-JSON to Class- part 4
5RSGC-Constructor – Deconstructor – part 5
6RSGC – DTO Mapper – part 6
7RSGC – Skinny Controllers- part 7
8RSGC-Builder Design Pattern – part 8
9RSGC- MetadataFromObject – part 9
10RSGC- Dynamic Mock – part 10
11RSCG- Method Decorator – part 11
12RSCG – Curry – Partial function – part 12
13RSCG- part 13 – IFormattable
14RSCG- part 14 – DP_Decorator
15RSCG- part 15 – Expression Generator
16RSCG- part 16 – Many Others
17RSCG- the book
18RSCG–Template Rendering- part 17
19CI Version
20HttpClientGenerator
21Query from database
22AutoRegister
23TinyTypes
24Static2Interface
25AppSettings
26Properties
27
Roslyn Source Code Generators

RSCG Example – Tiny Types – Part 23

 

 

name BaseTypes
nuget

https://www.nuget.org/packages/AndreasDorfer.BaseTypes/

link https://github.com/Andreas-Dorfer/base-types
author Andreas Dorfer

Generated tiny types from any value type
 

The code that you start with is


    [Int] public partial record DepartmentId;

    public Employee GetFromId(int idDepartment, int idEmployee)

    {

        

        return new Employee()

        {

            ID = idEmployee,

            DepartmentId = idDepartment,

            Name = "Andrei " + idEmployee

    

        };

    }

    public Employee GetFromId(DepartmentId departmentId,  EmployeeId employeeId)

    {

        return GetFromId(departmentId, employeeId);

    }


The code that you will use is



    e.GetFromId(10, 34);

    e.GetFromId(new DepartmentId(34), new EmployeeId(10));

 

The code that is generated is


    [System.ComponentModel.TypeConverter(typeof(AD.BaseTypes.Converters.BaseTypeTypeConverter<DepartmentId, int>))]

    [System.Text.Json.Serialization.JsonConverter(typeof(AD.BaseTypes.Json.BaseTypeJsonConverter<DepartmentId, int>))]

    sealed partial record DepartmentId : System.IComparable<DepartmentId>, System.IComparable, AD.BaseTypes.IBaseType<int>

    {

        public DepartmentId(int value)

        {

            this.Value = value;

        }

        public int Value { get; }

        public override string ToString() => Value.ToString();

        public int CompareTo(object? obj) => CompareTo(obj as DepartmentId);

        public int CompareTo(DepartmentId? other) => other is null ? 1 : System.Collections.Generic.Comparer<int>.Default.Compare(Value, other.Value);

        public static implicit operator int(DepartmentId item) => item.Value;

        public static DepartmentId Create(int value) => new(value);

    }

Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/TinyTypes

All RSCG

NrBlog Post
1RSCG–part 1
2RSCG- AppVersion–part 2
3http://msprogrammer.serviciipeweb.ro/2021/02/17/rsgc-enum-part-3/
4RSGC-JSON to Class- part 4
5RSGC-Constructor – Deconstructor – part 5
6RSGC – DTO Mapper – part 6
7RSGC – Skinny Controllers- part 7
8RSGC-Builder Design Pattern – part 8
9RSGC- MetadataFromObject – part 9
10RSGC- Dynamic Mock – part 10
11RSCG- Method Decorator – part 11
12RSCG – Curry – Partial function – part 12
13RSCG- part 13 – IFormattable
14RSCG- part 14 – DP_Decorator
15RSCG- part 15 – Expression Generator
16RSCG- part 16 – Many Others
17RSCG- the book
18RSCG–Template Rendering- part 17
19CI Version
20HttpClientGenerator
21Query from database
22AutoRegister
23TinyTypes
24Static2Interface
25AppSettings
26Properties
27
Roslyn Source Code Generators

AMA.NET 2

In fiecare joi, la ora 21, o sa tin o sesiune de AMANET – intrebati-ma orice despre .NET .  De preferinta, .NET Core – dar merge si .NET Framework, arhitectura, backend, Razor, MVC, orice care are legatura cu C# . Linkul  pentru video este  https://meet.google.com/idm-gcxj-enb  si cel de la google https://calendar.google.com/event?action=TEMPLATE&tmeid=MTdhZTVnOWZvdTk3ZTJzMjVzMW41bnI5c2FfMjAyMTA4MDVUMTgwMDAwWiBpZ25hdC5hbmRyZWlAbQ&tmsrc=ignat.andrei%40gmail.com&scp=ALL .

Va astept !

AMA.NET

In fiecare joi, la ora 21, o sa tin o sesiune de AMANET – intrebati-ma orice despre .NET .  De preferinta, .NET Core – dar merge si .NET Framework, arhitectura, backend, Razor, MVC, orice care are legatura cu C# . Linkul  pentru video este  https://meet.google.com/idm-gcxj-enb  si cel de la google https://calendar.google.com/event?action=TEMPLATE&tmeid=MTdhZTVnOWZvdTk3ZTJzMjVzMW41bnI5c2FfMjAyMTA4MDVUMTgwMDAwWiBpZ25hdC5hbmRyZWlAbQ&tmsrc=ignat.andrei%40gmail.com&scp=ALL .

Va astept !

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.