The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,835 other subscribers

Archive for the ‘Software Development’ Category

Some Markdown links on phrasing more difficult markdown for correct rendering

Posted by jpluimers on 2019/08/20

After blogging on Markdown notes in 2014, Markdown support has come a long way. It also means that the documents written in Markdown has become more complex, and that more tools can render it.

Given the vague aspects of many Markdown dialects, rendering can be troublesome (see my post Babelmark 2 online Markdown checker), so below are some links on some aspects I had trouble with getting right.

Note that there are two markdown linters:

Sometimes, issues are present in one, but not in the other; see:

The command line interface to the Ruby version is easier to install than the JavaScript version as everything is in one gemmdl, unlike the npm, where the cli is in markdown-cli and the library in markdownlint.

–jeroen

Related:

Read the rest of this entry »

Posted in *nix, *nix-tools, Development, Lightweight markup language, MarkDown, pandoc document converter, Power User, Ruby, Software Development | Leave a Comment »

Python line continuation: only use backslash if it gives cleaner code

Posted by jpluimers on 2019/08/20

Since Python is a [WayBack] line-oriented programming language, sometimes you want to wrap longer lines into more readable shorter ones.

Many people struggle with this, see for instance these questions (and excellent answers!):

This struggle is likely why it made it to the [WayBack] style guide. Relevant sections are below.

I had this struggle wile passing multiple parameters to a method creating a very long line, but found I did not need a line continuation as the Python language understands this construct perfectly fine:

    threadManager.append(
        UrlMonitorThread(monitor, "http://%s" % targetHost),
        SmtpMonitorThread(monitor, targetHost, 25),
        SmtpMonitorThread(monitor, targetHost, 587),
        SshMonitorThread(monitor, targetHost, 22))

You could use the line continuation backslash to do this, but often that is not needed or a better way exists (for instance wrapping an expression in parentheses), so here are are the relevant style guide sections:

Code lay-out

Indentation

Use 4 spaces per indentation level.

Continuation lines should align wrapped elements either vertically using Python’s implicit line joining inside parentheses, brackets and braces, or using a hanging indent[7]. When using a hanging indent the following should be considered; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.

Maximum Line Length

Limit all lines to a maximum of 79 characters.

For flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters.

Limiting the required editor window width makes it possible to have several files open side-by-side, and works well when using code review tools that present the two versions in adjacent columns.

The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.

Backslashes may still be appropriate at times. For example, long, multiple with-statements cannot use implicit continuation, so backslashes are acceptable:

with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

Make sure to indent the continued line appropriately.

Should a line break before or after a binary operator?

For decades the recommended style was to break after binary operators. But this can hurt readability in two ways: the operators tend to get scattered across different columns on the screen, and each operator is moved away from its operand and onto the previous line. Here, the eye has to do extra work to tell which items are added and which are subtracted:


To solve this readability problem, mathematicians and their publishers follow the opposite convention. Donald Knuth explains the traditional rule in his Computers and Typesetting series: “Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations” [3].

Following the tradition from mathematics usually results in more readable code:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth’s style is suggested.

–jeroen

Posted in Development, Python, Scripting, Software Development | Leave a Comment »

… compare two JSON structures and pin-point … the differences – – Nicholas Ring – Google+

Posted by jpluimers on 2019/08/20

I’ve added a few WayBack/Archive.is links to the interesting comments by Zoë Peterson from Scooter Software (of Beyond Compare fame) at [WayBack] … compare two JSON structures and pin-point … the differences – – Nicholas Ring – Google+:

Beyond Compare 4 has an optional “JSON sorted” file format that uses jq to pretty print and sort JSON data before comparing it. It’s not included out of the box yet, but you can get a copy here:

If you’re interested in an actual algorithm and not just an app, I don’t have a suggestion handy, but could dig one up. Tree alignment is more complicated than sequence alignment and we did do research into it, but it was quite a few years ago and didn’t get incorporated into BC. XML alignment algorithms were being actively researched back in the aughts and they should trivially transfer to JSON.

It looks like our research mostly ended around 2002, and I wasn’t personally involved in it, so I don’t know how helpful this will be, but here’s what I have:

The general idea in the thread is that JSON – though not as formalised as XML – does have structure, so if you can normalise it, then XML ways of differencing should work.

Normalisation also means that you need to normalise any floating point, date time, escaping, quoting, etc. Maybe not for the faint of heart.

–jeroen

Posted in *nix, *nix-tools, Beyond Compare, Development, diff, JavaScript/ECMAScript, jq, JSON, Power User, Scripting, Software Development, XML, XML/XSD | Leave a Comment »

TestInsight provides a local JSON web-server from the IDE for the test-runner to communicate from

Posted by jpluimers on 2019/08/15

Stefan Glienke shared the TestInsight default JSON web-server location with me through chat; I like it!

Some endpoints:

The mechanism for accessing this JSON server are implemented in the TestInsight.Client.pas

You can find the endpoint base URL in TestInsightSettings.ini which by default looks like this:

[Config]
BaseUrl=http://WIN10-DELPHI:8102

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

When Powershell function won’t work: you define them with commas and parentheses, but call them with spaces and no parentheses

Posted by jpluimers on 2019/08/15

The function or command was called as if it were a method. 
Parameters should be separated by spaces. For information about 
parameters, see the about_Parameters Help topic.

Every now and then I bump into the above error. The reason is this:

  1. Functions are defined with commas between parameters and parentheses around them
  2. One-parameter functions can be called with one parameter surrounded by parentheses
  3. Multi-parameter functions need to be called with spaces between parameters and no parentheses surrounding them

Confused? #MeToo

The problem: [WayBackabout_Parameters_Default_Values | Microsoft Docs

Based on [WayBack] Powershell function won’t work.

–jeroen

Posted in CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

Delphi, SHA-3 and streaming

Posted by jpluimers on 2019/08/15

If I ever need to use SHA-3 in Delphi: [WayBack] Does anyone know of any implementations of SHA-3, that can support TStream? – Nicholas Ring – Google+

The comments have a nice list of libraries supporting SHA-3, and how to do streaming hashing.

–jeroen

Posted in Delphi, Development, Software Development | 1 Comment »

Visual Studio Code direct download links

Posted by jpluimers on 2019/08/14

Visual Studio Code download links:

Via:

–jeroen

Posted in .NET, Development, Software Development, vscode Visual Studio Code | Leave a Comment »

PowerShell: be careful using `-ReadCount` on `Get-Content`

Posted by jpluimers on 2019/08/14

I learned this the hard way: [WayBackDifferent result when using -ReadCount with Get-Content: because -ReadCount delivers data in chunks, the filter after [WayBack] Get-Content (Microsoft.PowerShell.Management) it will only filter on those chunks. If the filter isn’t prepared for that, it might only filter the last chunk.

So do not use for instance [WayBack] Select-String (Microsoft.PowerShell.Utility) on it, but perform your own [WayBack] ForEach-Object (Microsoft.PowerShell.Core) aliased as foreach like in [WayBack] Get all lines containing a string in a huge text file – as fast as possible?:

Get-Content myfile.txt -ReadCount 1000 |
  foreach { $_ -match "my_string" }

A more elaborate example is at [WayBack] How can I make this PowerShell script parse large files faster?.

–jeroen

Posted in CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

What is ‘if __name__ == “__main__”‘ for?

Posted by jpluimers on 2019/08/14

One of the things when I learned Python was that in some scripts I found a block starting with a statement like this:

if __name__ == '__main__':

It looked like an idiom to me, and indeed it is: [WayBack] What is ‘if name == “main“‘ for?.

It allows a file to be both used as “main” standalone program file and a module. That section of code will not be executed if it is loaded as a module.

Part of the idiom is also to put your code in a separate method so this block is as short as possible.

if __name__ == '__main__':
main()

Via: [WayBack] Why is Python running my module when I import it, and how do I stop it? (thanks user166390 and Jeremy Banks for the answers there)

–jeroen

Posted in Development, Python, Scripting, Software Development | Leave a Comment »

QualityCentral 56524: tanh function from Delphi 7 till Delphi XE was buggy; XE2 fixed it

Posted by jpluimers on 2019/08/13

In case you maintain code in older versions of Delphi, be aware that the function tanh was broken starting in Delphi 7 and only got fixed in Delphi XE2: QualityCentral QualityCentral 56524: tanh function from Delphi 7 till Delphi XE was buggy; XE2 fixed it.

For big inputs, it would just fail, instead of returning 1.

The reason is that in the buggy versions, tanh got replaced from an old working version into a simple sinh/cosh, which mathematically is correct, but if your numeric data type has limited accuracy, you need to account for the boundaries where the result fits, but intermediates do not.

the [WayBack] Math.Tanh Function implements the hyperbolic tangent, for which you can find the definition at Hyperbolic function – Wikipedia: Definitions.

By now it is implemented for all floating point types the same way (only the parameter type changes in each implementation)

function Tanh(const X: Extended): Extended; overload;
const
  MaxTanhDomain = 23;
  C1of3 = 1/3;
  CBorder = 1.8145860519450699870567321328132e-5; // 2 ^(-63 / 4)
  CLn2Div2 = 0.34657359027997265470861606072909; // Ln2 / 2
var
  y, z: Extended;
begin
  FClearExcept;
  case TExtendedRec(X).SpecialType of
    fsPositive,
    fsNegative:
      begin
        z := X;
        if X < 0 then z := -z;
        if (z > MaxTanhDomain) then
          Result := 1.0
        else if (z < CBorder) then
          Result := z  - z * z * z * c1of3
        else if (z < CLn2Div2) then
        begin
          y := ExpMinus1(2*z);
          Result := y / (2 + y);
        end
        else
        begin
          y := Exp(2*z);
          Result := 1 - (2/(y + 1));
        end;
        if X < 0 then Result := -Result;
      end;
    else
      Result := X;
  end;
  FCheckExcept;
end;

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »