Voice Transcription

I’ve been noodling around with transcription software, and encountered whisper, which does a great job of transcribing. It’s the usual python-based solution, which is pretty good at knocking out a transcription, but it’s a tad on the slow side.

Then, when listening to the Changelog podcast, they were talking to Georgi Gerganov, who’s created whisper.cpp, which is an implementation in C++. I am completely bowled over with not surprise that it’s faster than the original python implementation.

… but… it’s faster by an order of magnitude. While the original python implementation can be done in hours, this can be done in minutes.

I think I’m going to stick to C++ and rust when I need the performance, thanks!

Dropping files on apps (Mac)

When you write an application, sometimes you want the application to open with one or more files. There’s the ubiquitous double-click to open with the default application, there’s the right-click and use the open with a specific application option.

So on the Mac, to support dragging-and-dropping onto the application icon, you need to declare that the app supports having that file type dropped upon it. So you go to the application file types, and add support for your file type. This will add something like the following to your application plist:

<key>CFBundleDocumentTypes</key>
<array>
	<dict>
		<key>CFBundleTypeName</key>
		<string>All Items</string>
		<key>CFBundleTypeRole</key>
		<string>Viewer</string>
		<key>LSHandlerRank</key>
		<string>Alternate</string>
		<key>LSItemContentTypes</key>
		<array>
			<string>public.content</string>
		</array>
		<key>NSDocumentClass</key>
		<string>NSDocument</string>
	</dict>
</array>

With this, when you drag-and-drop a file onto your application, the application will receive a message saying the file has been dropped on your application. We limit this to files, by specifying the content type as public.content. If you wanted to accept any file-system based things, you would specify public.item. There is an inventory of the publicly declared types on the apple website.

To handle this, in objective C, you would add an openFile AppDelegate method, which would receive the name of the file, and allow you to process it – for example:

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
    NSLog(@"%@", filename);
    return YES;
}

In this case, all the code does is display the name of the file in the log, and state that the event has been handled.

This code can be seen on GitHub – this is tag v1.0 of the program. I’ll be adding more functionality in later posts.

Integrating the paypal SDK in an android app with SDK 31

I encountered a stackoverflow question which did not have anywhere near enough details to debug what was happening, and contained pasted images.

The problem was that the developer was attempting to integrate the Paypal Checkout SDK into an Android app, and it was not building with a ‘merge resources’ error.

When I pointed the developer to the ‘how to fix’ question, they didn’t believe it would fix their problem and very soon afterwards the question was closed with ‘needs more details’.

It had scratched an itch with me, so I started a new android SDK project to test this integration myself. The github repository is available for all to see.

I started with a main branch without any paypal SDK integration. It builds and runs.

Then I created an ‘adding_paypal’ branch, where I was introducing the paypal SDK. Step one was adding the SDK. I too experienced the ‘merge resources’ error, and when I clicked back on the log I saw:

...PaypalSdkIntegration/app/src/main/AndroidManifest.xml Error:
android:exported needs to be explicitly specified for <activity>. Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
...PaypalSdkIntegration/app/src/main/AndroidManifest.xml Error:
android:exported needs to be explicitly specified for <activity>. Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.

There is a very simple solution to this – revert the targetSdk to 30, instead of the 31 that it was currently set to. This is what I did for the initial commit.

Then I sat down, and looked at the ‘merged manifest’. Any <activity> items that didn’t have an android:exported tag, needed to be merged in my own AndroidManifest.xml.

Firstly, add the tools namespace to the AndroidManifest.xml file, so in the <manifest> tag, you add:

xmlns:tools="http://schemas.android.com/tools"

Then add entries for all the activities that were present in the merged AndroidManifest which don’t have an android:exported property, and apply a merge flag for them. The true/false value I chose was based on the premise:

True: If there was an intent filter.
False: When there are no intent filters.

Merge items look like:

<activity android:name="com.paypal.authcore.authentication.TokenActivity"
android:exported="false"
tools:node="merge" />

While I was writing up this article, I noticed that I had completely inverted the logic, so I fixed it in a third commit to the branch.

I hope this helps someone who’s having the same problem. It can be applied when you encounter any project that has the same merged manifest issue. The general procedure is:

  • Set to targetSdk 30
  • Build, which should work cleanly
  • Look at all activities that do not have an android:exported tag and add a merge node in your own manifest file.
  • Set to targetSdk 31
  • Build, which should now build correctly.

On names and collation

Computers are wonderfully efficient at simple and mundane tasks, such as sorting lists of things. However, the most basic sorting done is the comparison of the character on a byte-by-byte basis. If we go back to the old days of ascii, this means that you end up with a case sensitive sorting, where capitals come ahead of lower case.

You then go to linux, and you start doing ls, and it ends up showing the list of filenames in a case insensitive manner and you go … that’s nice. You then go to OSX and do an ls, and it ends up showing the list of files in a case sensitive manner and you go – dude, not nice. Turns out that OSX’s libc uses la_LN.US-ASCII for collation on all en_ locales – i.e. plain old ascii.

Finder does not use this sorting, It’s sorting is done by sorting the names using the routine UCCompareTextDefault, with options that allow you to specify case insensitivity, and treating numbers as numbers, as well as some others. It’s pretty fancy.

However I’m talking about names. There are a wide variety of rules related to names, and I’ve had to do some odd stuff in my past.

The first thing I’ve been asked, is to omit the ‘The’ from collation – e.g. titles containing The as the start are instead sorted by the second word – so, for example The Last Supper would be listed under L, instead of T. Very much how you find it in the library under Last Supper, The.

Then there are Irish names. Please sort in library order was the request.

I had no idea how much of a rathole this was

First – accents or fadas, as we call them come after the letter of the same character so a, á, i, í, etc

Then stem the surname, for the most part, so Ó Loingsigh is sorted under L. There are a lot of surname prefixes in Irish – De, Fitz, Ó, Uí, Ní, Nic, Mac, Mc, Mag, Mhig, Nig, Mac Giolla, Ua – oh my! In general, you’re not supposed to collate under the prefix; except when it’s a Mac or Mc – they’re generally considered sorted as if Mc and Mac are the same. so McCarthy, MacLysaght…

I’ve been trying to track down the article that I used as a basis for this, but it appears to be based on an article by O’Deirg, — “Her infinite variety” – on the ordering of Irish surnames with prefixes, especially those of women.’ An Leabharlann 10 (1), 14–16. The best source reference to this I’ve been able to track down is an article by Róisín Nic Cóil, titled Irish prefixes and the alphabetization of personal names, which contains the common practices. They’re a lot lazier than the requested ordering I was asked to use, which is more in line with O’Deirg’s work.

Which brings me back to the original reason for writing this article — someone commented that all the books in their collection that started with the word The were sorted into the pool of books starting with T, rather than with their second name. Rather than um actually’ing the conversation, I decided to share my experience in the area with others.

Sorting/Collation … like date and time handling is complicated if you want to do it ‘right’, and right depends on where you’re asking from.

The dangers of upgrading

One of the guys in the office was having trouble since the upgrade to python3.6 – a bunch of test code was breaking when run under the debugger.

The issue seemed to be related to the use of pexpect 4.6 in the new environment as opposed to pexpect 3.3 in the old environment.

This is made very difficult to debug as the ptyprocess code closes all the file descriptors of the child process before attempting to exec. As a result random exceptions were being swallowed, the entire thing was crashing out, and the code was locking up in an error read loop.

I hemmed and hawed about downgrading to the 3.3 version of pexpect, but decided to investigate further, rather than leave the problem as is.

Addressing the debugging problem involved replacing all the code that closed all the file descriptors with code that marked all the file descriptors as close on exec, so that when I saw the exception, I was able to deal with it. This was done in the ptyprocess module. The solution is linux only, but TBH at this time it’s all I’m concerned with.

Addressing the pexpect problem involved just removing the code that re-encoded the arguments when the encoding argument was passed, and just leave them as-is.

The confusion is because encoding was for the I/O, not for the arguments on the command line, and when the change was made it relied on this argument, rather than adding an extra argument to deal with it.

Fixes the problem in my case, but it was a complete pain to debug.

Hope in every box

Imagine if life stretched out in a single span from birth to death, and all you have is a long stretched out span between the start and then end, with no pause in between.

It would be absolute hell on earth. How could you bear to survive in a world like that? A never ending stretch until the precious final release of death.

However it’s not that case — life is, instead, broken down into little boxes.

Each box is a day. Each box is separate and distinct. Sometimes when you’re in a box it seems like that’s all there is and there’s no way out. Sometimes you look at another box and think that it’s an impossible goal because it looks so difficult to get to as you don’t have the skills or experience to get there.

The trick is though, every day you have choices as to where you want to go — there are exits to the box doing in different directions. Some of the directions are positive, and some of the directions are negative. Sometimes, you may have slipped so far into the negative that you cannot conceive of getting to the positive.

However, the thing about the individual boxes is that you only need to deal with the situation one box at a time.

Whether the box is getting practice in your writing,

or the box is managing to to another day without a drink,

or the box is learning more about yourself…

It’s only a small box that you need to get through; you’re not trying to deal with the entirety of your life, you’re just trying to deal with this one small thing called now.

An important thing to remember, though, is that you don’t always have to ‘make progress’. Sometimes the only thing you can do is just get through that single box. The best thing about all these individual boxes is that you get the opportunity to try again the next time. Because no matter how bad it seems to be at this moment in time, you will have another opportunity the next time as long as you get the fact that there will be another time. It’s just a single box away.

We need to aim for progress, not perfection; one day at a time.

Originating Video

(Floating point) math is hard

On websites like StackOverflow, if you post something about floating point math, it will get closed very quickly as a duplicate of the ‘is floating point broken’ question. Very often it is a duplicate of that question, however there are occasions when this is not the case.

The general question is typically how come 1.1 + 2.2 != 3.3?. There are a lot of resources about this. The long and the short of it is that binary representations of floating point numbers are not the actual numbers, but close approximations to them, so as a result equality sometimes isn’t, and you end up having to do ‘fudge’ math (a == b becomes fabs(a – b) < fudge). It’s great fun (and I mean that in the most sarcastic manner possible).

Sometimes, it’s about the display of floating point numbers, and it’s really frustrating when the question gets closed for the wrong reason. This can be especially frustrating for the OP, who may be new to the site and gets a poor impression from this.

The issue, in this case was about missing precision on the display of java floating point values.

In java the code:

float f = 2.0f / 3.0f;
System.out.println(f);

Will only display 7 decimal places. This is because it’s a 32bit float, and can only represent up to that level of precision.

The code:

double d = 2.0 / 3.0;
System.out.println(d);

Will display 15 decimal places. This is because it’s a 64bit float, which can represent up to that level of precision.

So, if you want 15 decimal places in the default number math, you need to use the double.

This is all moot if you’re dealing with money. I really do hope you’re not using float to represent money. That’s how you get an audit. In the words of a great philosopher, that’s a German car, the ‘T’ is silent 🙂

On walled gardens

I recently downloaded an application for doing ‘time since’ tracking. Tracking these stats is not something I would associate with cloud based services – I would anticipate the data being on-device, and not leaving unless you explicitly chose to export it.

The first thing I encounter is a login screen. It asks for an email and password, and if I don’t have an account, it asks to create one; obviously requiring an email and password.

Closed app,

Deleted from device.

I have no way of interacting with the app without an account, as a result I don’t know if it’s good or bad, all I know is that it’s asking for some PII, and I’m not willing to take the chance that it’s trustworthy.

Security – get the facts

This is similar to the slippery slope of drugs and alcohol for addicts – somewhat humorous (from @thegrugq):

“I used to use 1024bit keys, then my friends switched to 2048, I felt I had to as well. Now I’m using 4096. Everyday”

#EncryptionGetTheFacts