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,854 other subscribers

Archive for the ‘Development’ Category

Public traffic ticked vending machines can have good user experience.

Posted by jpluimers on 2021/06/29

At the bottom a few examples on on how not do do user experience.

Most of them are related to public traffic ticket vending machines, which seem to have a common pattern of having very low usability.

Good UX is possible

There is one example I know that has quite a good user experience, because taking usability into account aspart of the design was done at the start of the project.

This is contrary to most machines: they are built by engineers just taking into account their needs and challenges: build from existing parts, allowing for easier serviceability, aiming for ease of manufacturing.

Dutch GVB did it differently: they hired Dutch design agency [WayBack] Fabrique to design and test the user experience before the whole machine went into production.

This resulted in a machine that combines easy usability, good servicing, and straightforward manufacturing process. In addition, an “extended” version that allows for non-electronic payment was designed and manufactured in the same go.

[WayBack] Fabrique

Fabrique is a strategic design agency, specialised in service design, app development, e-commerce and website design. Discover Fabrique!

(Note I am not affiliated, nor endorsed by Fabrique. I just think they did a very good job)

Here are some pictures of the designed and manufactured machines; the vertical stripes light up the place where the next user interaction takes place:

Read the rest of this entry »

Posted in Development, Software Development, Usability, User Experience (ux) | Leave a Comment »

Hopefully datendomina (@sys_adm_ama) has followed up with some cool vi tips…

Posted by jpluimers on 2021/06/28

I hope that datendomina (@sys_adm_ama) has followed up with some cool vi/vim tips.

Though I can do basic editing (far more than quit-without-saving) and know about he various mode, I still feel not proficient.

[WayBack] Jeroen Pluimers on Twitter: “LOL! Boy was I glad that after finding my way in Ed and sed on SunOS in the 1980s, I discovered vi. Still not proficient in it (and I probably never will). However, knowing some of the basics allowed me to visually edit any file on any Unix like system. That’s still gold to me.…”

It also made me discover [WayBack] ed(1) Conference (@ed1conf) | Twitter.

One important tip:

[WayBack] Kristian Köhntopp on Twitter: “vi movement Kommandos haben System. Erkenne und lerne das System. hjkl + prefix+hjkl, Marken, prefix+jump to mark und so weiter. Und bleibe von den verblödeten Plugins weg. Die braucht kein Mensch und machen vim nur langsam im Start und kompliziert.”

The original thread, which I hoped would get longer: [WayBack] Thread by @sys_adm_ama: “Ich lerne jetzt vi(m). Klingt beknackt, oder?se […]”

Ich lerne jetzt vi(m).

Klingt beknackt, oder? Aber ich hab überlegt: ich möchte effizienter werden, meinen Kram stressfreier bewältigen. Und ich finde, es bietet sich an da an Baustellen anzusetzen, die täglich relevant sind. Und vi(m) nutze ich in der Tat täglich.

1/

Aber auch wenn ich ihn nutze und über den »Hilfe, wie komm ich aus dem Editor wieder raus?!«-Witz nur sehr müde die Augen rolle gehe ich davon aus, dass ich nicht mal einen Bruchteil der Möglichkeiten ausschöpfe, die er bietet (1. Release 1976, älter als ich!). Das ist spannend.
Das ist jetzt meine Mini-Challenge, auf die ich jeden Tag eine Viertelstunde verwenden will: wenn ich eine Funktion brauche mich nicht mehr drum herum zu hacken, sondern recherchieren wie es richtig geht und das dann gefälligst auch verinnerlichen. Mal sehen, ob das so klappt

3/

In dem Zuge will ich auch wieder verstärkt (neo)mutt in Verbindung mit vim nutzen – das wäre ein wunderbares tägliches Training 😎 Mails schreiben muss man irgendwie immer.

neomutt bietet leider auch einen Eimer voll Funktionen, die ich noch nicht ordentlich nutze. Gnah.

4/

An euren Replies erkenne ich, dass das mit dem »sich die Kürzel merken« echt heikel zu sein scheint 🤔 Wie handhabt ihr das im Alltag? Einfach ein paar Basics wie :u und CTRL+r und gut ist? Ich bin neugierig. Oder nutzt ihr alle nano? (Ich glaub, dann muss ich entfolgen) 😂
Nur als kleinen Zwischenstand: nach dem Lesen eurer Antworten schließe ich, dass ich mich mit meinem Kenntnisstand nicht verstecken muss 😂 Da hat mir der virtuelle Schulterblick schon weiter geholfen.

/5
vi(m), weil ich Admin bin und dieses Tool auf jedem System und ohne X-Geraffels üblicherweise vorfinde (wenn auch bei neueren Installationen dieser absurde „visual mode“ der Default ist 😳). Auch unter (Open)Solaris, IRIX, was weiß ich.

/6

Eben hab ich das Buch von @MasteringVim aus der Packstation gezogen (extrem vielversprechend!) – und klar, ich werde berichten 😎 Ich bin sehr gespannt.

/7ed

–jeroen

Read the rest of this entry »

Posted in *nix, *nix-tools, Development, ed, Power User, Scripting, sed, sed script, Software Development, vi/vim | Leave a Comment »

I don’t want to learn your garbage query language · Erik Bernhardsson

Posted by jpluimers on 2021/06/24

Interesting read:

This is a bit of a rant but I really don’t like software that invents its own query language. There’s a trillion different ORMs out there. Another trillion databases with their own query language. Another trillion SaaS products where the only way to query is to learn some random query DSL they made up.

Source: [WayBackI don’t want to learn your garbage query language · Erik Bernhardsson

Related:

Via: [WayBack] Die wichtigste Funktion in jedem ORM ist der Notausgang. Also, wie man literales SQL durch das Ding durch piped, ohne daß der ORM rein pullert. – Kristian Köhntopp – Google+

–jeroen

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

DCOM calls from thread pool threads: CoInitialize/CoUnitialize location and expensiveness?

Posted by jpluimers on 2021/06/24

Interesting takeaway from [WayBack] DCOM calls from thread pool threads

call CoInitialize* at the start, and call CoUninitialize before returning. Expensive, but necessary

Related:

–jeroen

Posted in .NET, C, C++, COM/DCOM/COM+, Delphi, Development, Software Development, Windows Development | Leave a Comment »

“No mapping for the Unicode character exists in the target multi-byte code page”

Posted by jpluimers on 2021/06/24

Usually when I see this error [Wayback] “No mapping for the Unicode character exists in the target multi-byte code page” – Google Search, it is in legacy code that uses string buffers where decoding or decompressing data into.

This is almost always wrong no matter what kind of data you use, as it will depend in your string encoding.

I have seen it happen especially in these cases:

  • base64 decoding from string to string (solution: decode from a string stream into a binary stream, then post-process from there)
  • zip or zlib decompress from binary stream to string stream, then reading the string stream (solution: decompress from binary stream to binary stream, then post-process from there)

Most cases I encountered were in Delphi and C code, but surprisingly I also bumped into C# exhibiting this behaviour.

I’m not alone, just see these examples from the above Google search:

–jeroen

Posted in .NET, base64, C, C#, C++, Delphi, Development, Encoding, Software Development, Unicode | Leave a Comment »

delphi – Is it possible to define {$IFDEF} for more than one directive at once? – Stack Overflow

Posted by jpluimers on 2021/06/24

[WayBack] delphi – Is it possible to define {$IFDEF} for more than one directive at once? – Stack Overflow:

–jeroen

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

Some notes on dumping IceCast ICY streams to get meta-data

Posted by jpluimers on 2021/06/23

Some links I want to investigate further.

This is difference in the header meta data of an icecast URL, than in the stream data.

The header meta-data you get from this cURL command (via [WayBack] linux – Catch Metadata from Icecast-audio-stream – Super User):

# curl -H "Icy-MetaData: 1" -v "http://icecast.omroep.nl:80/radio2-bb-mp3" > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 145.58.53.154...
* TCP_NODELAY set
* Connected to icecast.omroep.nl (145.58.53.154) port 80 (#0)
> GET /radio2-bb-mp3 HTTP/1.1
> Host: icecast.omroep.nl
> User-Agent: curl/7.54.0
> Accept: */*
> Icy-MetaData: 1
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: audio/mpeg
< Date: Mon, 01 Jul 2019 06:46:33 GMT
< icy-br:192
< ice-audio-info: samplerate=48000;channels=2;bitrate=192
< icy-br:192
< icy-genre:Mixed
< icy-metadata:1
< icy-name:NPO Radio2
< icy-pub:0
< icy-url:http://www.radio2.nl
< Server: Icecast 2.4.0-kh10
< Cache-Control: no-cache, no-store
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type
< Access-Control-Allow-Methods: GET, OPTIONS, HEAD
< Connection: Close
< Expires: Mon, 26 Jul 1997 05:00:00 GMT
< icy-metaint:16000
< 

The content meta-data you can for instance get with node.js in a call like [WayBack] https://colon.roderickgadellaa.com:8001/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3:

{"ok":true,"code":200,"error":false,"data":{"headers":{"content-type":"audio/mpeg","date":"Sat, 29 Jun 2019 17:07:03 GMT","icy-br":"192, 192","ice-audio-info":"samplerate=48000;channels=2;bitrate=192","icy-genre":"Mixed","icy-metadata":"1","icy-name":"NPO Radio2","icy-pub":"0","icy-url":"http://www.radio2.nl","server":"Icecast 2.4.0-kh10","cache-control":"no-cache, no-store","access-control-allow-origin":"*","access-control-allow-headers":"Origin, Accept, X-Requested-With, Content-Type","access-control-allow-methods":"GET, OPTIONS, HEAD","connection":"Close","expires":"Mon, 26 Jul 1997 05:00:00 GMT","icy-metaint":"16000"},"metadata":{"StreamTitle":"AUDIOLINK-AUDIO-FTP-SERVER - +EJ+  Ons Uuropener"},"timestamp":1561828023103,"cacheValidUntil":1561828038103},"request":{"protocol":null,"slashes":null,"auth":null,"host":null,"port":null,"hostname":null,"hash":null,"search":"?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3","query":{"url":"http://icecast.omroep.nl:80/radio2-bb-mp3"},"pathname":"/get/id3/","path":"/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3","href":"/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3"}}

This was at a time where the Dutch NPO Radio 2 had trouble with their ID3 service as the first part stopped refreshing for days: "metadata":{"StreamTitle":"AUDIOLINK-AUDIO-FTP-SERVER - +EJ+ Ons Uuropener"}

Some links that will help me eventually dump this from the command-line:

–jeroen

Posted in Development, IceCast, Media Streaming, Software Development | Leave a Comment »

Disable Filtered Gap – Scooter Forums

Posted by jpluimers on 2021/06/23

There is a short thread mentioning [WayBack] Disable Filtered Gap – Scooter Forums (Issues concerning Text Compare sessions.)

It is the feature that when you select “Diffs” or “Same” on the toolbar on menu in a “Text Compare” (or similar, like XML compare), you see only the differences (or equalities when you selected “Same”).

There also will be small plus signs (+) in the gutter with the hover text “Expand Filtered Gap” on it to expand that gap and show the equalities (or differences when you selected “Same”).

There are two problems that basically make this feature very hard to use, which both stem from the need to view context around a difference in order to understand the proper meaning of that difference:

  • you cannot expand or collaps the “Filtered Gap” by keyboard
  • the “Number of context lines” in the “Text editing” part of the “Options” is not adhered to

Too bad as this could have been such a useful feature.

–jeroen

Posted in Beyond Compare, Development, Power User, Software Development | Leave a Comment »

XMLDoc Delphi source code documentation generation – some links

Posted by jpluimers on 2021/06/23

There is very little information on how to use the XMLDoc documentation formatting in your Delphi source code.

So here are some links for me to get started:

XmlDoc comments can get verbose because of the lengthy XML syntax.

Hiding them in regions can help, for instance with the plugin at [WayBack] Fast-Forward »: XML Documentation in Delphi 2006.

I still should try NDoc – Wikipedia for post processing of the Delphi generated XML file, but since I almost exclusively use the internal IDE viewer, that is good enough for me now.

Syntax

Most of the above links talk about tooling, but little about syntax. Luckily, it is very similar to the C# XML Documentation syntax documented by Microsoft:

DevJet has a nice document describing all Delphi supported tags in [WayBack] Delphi-Documentation-Guidelines.pdf (via [WayBack] DevJet Software » Delphi Documentation Guidelines) including the tags mentioned in [WayBack] Dr.Bob Examines… #100: Generating Documentation.

For comparison:

One Delphi specific thing on the see tag.

The see tag accepted a syntax like UnitName|IdentifierName (see for instance [WayBack] How/under which circumstances does the tag in Delphi xml comments actually work? – Stack Overflow).

In Delphi 10.1 Berlin, sometimes that did not work and I had to use the UnitName.IdentifierName syntax.

The difference is how it is displayed: UnitName|IdentifierName shows as IdentifierName, whereas UnitName.IdentifierName is shown in full.

Sometimes one or the other is unclickable.

In the Delphi IDE, href references do not work

Similar to C# and the Visual Studio IDE, any href reference will not work in the IDE itself. See [WayBack] C# XML Documentation Website Link – Stack Overflow.

In Delphi, the same para element for paragraphs is used as in C#

Documented in the DevJet documentation, the para element works for paragraphs just like it does in the C# example at [WayBack] How to add a line break in C# .NET documentation – Stack Overflow.

Example

A few important tags:

   TParentedTest = class;
   IParentedTest = ISmartPointer<TParentedTest>;
   /// <summary>
   /// <para><see cref="Data.DataRecord|TJoinableDataRecord" /> that can be parented.</para>
   /// <para>The first time you obtain <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" />, it will create one for you (so be careful not to recursively call <c>Parent</c>).</para>
   /// </summary>
   TParentedTest = class(TTest)
   strict private
     /// <summary>
     /// <para>Backing field of <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" />.</para>
     /// <para>Referenced by <c>interface</c> <see cref="System|IInterface" /> instead of <c>class</c> <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" /> as that prevents use-after-free access violations.</para>
     /// </summary>
     FParentInterface: IInterface;
   public
     class function CreateI(const Name: string): IParentedTest;
     /// <summary>
     /// <para>Ensures there is a parent by creating a new <see cref="UnitTest.Query.JoinHelper|TParentedTest" /> if there is none yet.that can be parented.</para>
     /// <para>Do not call recursively, as it will keep creating parents in an endless loop.</para>
     /// </summary>
     function Parent: TParentedTest;
     destructor Destroy; override;
   end;

–jeroen

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

File Line Count: “built-in” line count for Windows

Posted by jpluimers on 2021/06/22

Windows if full of undocumented gizmo’s, like find alternative for wc -l counting all lines in a file: [WayBack] File Line Count

Use FIND command to count file lines, store line count into a variable.

Description: Running the FIND command with option /v and empty search string will find all lines
Running the FIND command with option /c will output the line count only.
The FOR command with option /f will parse the output, the line count in this case, and the set command put the line number into the cnt variable.
Script:
1.
2.
3.
4.
set file=textfile.txt
set /a cnt=0
for /f %%a in ('type "%file%"^|find "" /v /c') do set /a cnt=%%a
echo %file% has %cnt% lines
Script Output:
 DOS Script Output
textfile.txt has 50 lines

[WayBack] Stupid command-line trick: Counting the number of lines in stdin | The Old New Thing

Windows doesn’t come with wc,
but there’s a sneaky way to count the number of lines anyway:

some-command-that-generates-output | find /c /v ""

It is a special quirk of the find command
that the null string is treated as never matching.
The /v flag reverses the sense of the test,
so now it matches everything.
And the /c flag returns the count.

The reason dates back to the original MS-DOS
version of find.exe,
which according to the comments appears to have been written
in 1982.
And back then, pretty much all of MS-DOS was written in assembly
language.

Via: batch file line count – Google Search and [WayBack] windows – How to count no of lines in text file and store the value into a variable using batch script? – Stack Overflow

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development, Windows Development | Leave a Comment »