Notes

Foodiary for Obsidian

Following my first plugin for Obsidian, I released the second one a couple of weeks ago. Counts calories, proteins, fats, and carbohydrates in food. It helps not to overeat out of nowhere — it’s rather difficult to judge by eye how much you’ve eaten today and whether you can afford that donut.

In short, a useful thing if you:

  1. Fatty (like me)
  2. Want to stop being fatty (like me)
  3. You take notes in Obsidian (like me) 🙂

In fact, there is a lot of software for this task. I tried some of them but was dissatisfied: it either has terrible design, is bugged, or is constantly trying to sell me a monthly subscription. In short, it's more annoying than helpful. I wanted something native, built into the usual routine; so, if routine settles in Obsidian, then the solution seems to suggest itself.

You can install the plugin directly from the program — the developers have already approved it. Otherwise, everything is simple: you write in a daily note what you ate and how much it weighed, and you receive a simple table sorted by calories with numbers by proteins, fats, and carbohydrates.

There are examples in the repository at the link above.

2024-04-14 done TypeScript Obsidian

Fastimer's Look

I just implemented Fastimer's rendering through callouts: this is an Obsidian mechanic that allows you to turn an ordinary quote into a designed block of text that attracts the reader's attention. You've probably seen blocks like “advice” and “pay attention” — these are callouts.

You can read more in Obsidian Help.

As a result, the timer now takes on a different color depending on the state: blue for an active fast, green for completed, and red for a failed one.

In addition, I made the text more compact and worked on styling:

Example

It turned out to be way nicer than the block of preformatted text as it was before.

2024-03-09 Obsidian TypeScript

Small Pleasures

I was wasting time at the supermarket checkout: it’s evening, there aren’t many customers anymore, but the elderly cashier is clearly tired and isn’t in too much of a hurry. Standing in front a tall, gray-haired man with a luxurious beard whiles away the time studying the rack of chocolates next to the cash register.

Finally, he takes a Snickers, twirls it in his hands thoughtfully. Then he pushes two more towards himself and, broadly, with visible pleasure, smiles into his mustache :)

2024-03-06 meanwhile Georgia

Not Only Everything

This commentary in the documentation for the WriteJSON() method of XDTOSerializer is enviably deep, I would say:

Not only everyhing

Well, yes. The method dumps data into JSON, not XML. So it’s hard to argue that not all value types can be packed into XML using it (to be precise, none). Such a pity that there is an obvious copy-paste from the help for WriteXML() further in the text! I almost decided that it was an Easter egg from the developers :)

2024-02-25

Fastimer for Obsidian

The Obsidian developers recently approved one of my TypeScript pet plugins — Fastimer. It is an intermittent fasting tracker that adds a new code block to your vault: you enter the start date of the fasting interval and get the date of its finish, the time until this moment, and a list of the zones to be passed.

The block shows an up-to-date picture every time Obsidian renders it, which means you can monitor your progress in real time. When a fasting window ends, you can enter the end date, and the code block will show the result: whether you managed to achieve the goal, how much time you fasted beyond the plan, and so on.

I'm thinking of improving the visual part a bit (currently, everything is displayed as plain text without any design). In addition, I want to add functions for calculating statistics so that you can draw cute graphs like Charts and show achievements. I already made the same in implementing the same application in Python, but I’m unlikely to return to it — it’s easier to solve the task in the Obsidian vault than to roll out an additional utility.

In short, check out the plugin! :) You can find it by name (Fastimer) in the Obsidian library, or install it manually from the repository.

2024-02-13 done TypeScript Obsidian

Do? Do Not?

Among our projects, we have one where two systems are communicating with each other: ERP and CRM. Data exchange is done well: a push'n'pull server has been set up, subscriptions to events have been registered, a REST API has been implemented, and so on. There are many other fascinating technical details, but I'm not talking about that now.

The exchange has various logic chains inside. For instance, if a new company appears in CRM, it sends the data to ERP. The other day, a problem appeared: a company was not sent from the CRM, no matter how many times you tried to write it. So we went to investigate, suspecting the worst: CRM is written in PHP (nothing personal; it’s just not our technical stack), and there’s a lot of different legacy stuff there. It's easier to shoot yourself in the foot than to blow your nose.

However, it didn't take much digging. We opened the company’s page in CRM and saw that he had the “Do Not Export To ERP” checkbox, which, in fact, blocked the sending. A manager made an obvious mistake.

Should we uncheck the box and close the ticket?

Well yes, but actually no

This will solve the problem with that particular company, but not the reason it appeared. It is actually in the interface, specifically in the name of the option: “do not” is used, which is advisable to avoid due to the fact that it is more difficult for users to read the wording correctly. By the way, this also applies to a simple “do”.

It is often difficult for programmers to understand why this is so: we are used to instantly calculating Boolean expressions in our heads, and variations like “not (not true)” are commonplace for us. But people with a different background can get confused. Just a little, but sometimes this is enough for them to perceive “do not export” as “do export” in the heat of the day, click the option, and move on.

To sum up, the solution is to rename the checkbox. “Disable Export” or “Stop Export” are both fine, for example. “Prohibit Export” also comes to mind, but it’s more about interpersonal relationships, and in general, a ban on doing something does not mean that it won’t be done :)

2024-01-14 work English

Last Meth

I'm digging into the code of an external component for 1C platform, published by its developers as an example. The good thing is: well, it can be compiled and if you tweak it a little — it does the job.

As for other things, there are a lot of bruh moments. For example, the project can't be opened in modern Visual Studio (you need to specify CMake manually). The code is quite sloppy; there is no documentation, comments, or formatting. Long story short: I believe, it can be difficult for a developer without solid experience in C++ to get the hang of this.

Was a bit amused by the naming in the code below:

long CAddInNative::FindMethod(const WCHAR_T* wsMethodName)
{ 
    long plMethodNum = -1;
    wchar_t* name = 0;

    ::convFromShortWchar(&name, wsMethodName);

    plMethodNum = findName(g_MethodNames, name, eMethLast);

    if (plMethodNum == -1)
        plMethodNum = findName(g_MethodNamesRu, name, eMethLast);

    delete[] name;

    return plMethodNum;
}

I see here the inexplicable love for abbreviations. What made the author name the variable “eMethLast”, not “eMethodLast”? They already created "wsMethodName" and "plMethodNum", after all.

Perhaps this is an Easter egg with a reference to Breaking Bad. Then I like it for sure :)

2023-12-17

Wrong Freeway Entrance

Have you ever taken the wrong freeway entrance? You need to drive to the next exit to turn around, but you hate every inch of travel because you're going away from your goal.

― Andy Weir, "The Martian"

Programmers have exactly the same emotions when they spend a long time working on something. They suddenly realize that part of it should be designed differently. Moreover, this is exactly what you have to do since it solves several problems at once. This is where technical debt is born.

However, right now you don’t change anything but continue to work with the part of the code that already exists. After all, you are professional, and you have a release date! You have to make it on time and then pay the debt, but you hate every inch of code you write because you're going away from your goal.

2023-11-14 code smell

Everyday Heroism

Some time ago, I was setting up Swagger for the internal API. While I was fiddling around, it became clear that some functionality did not need to be included in the documentation. I was looking for a way to do this without crutches and came across a funny question on GitHub.

What's funny, you ask? Well, I involuntarily remembered Mista. Among 1C developers, this is synonymous with the word “toxicity”: if you ask anything there, you get a bucket of slop by the collar instead of an answer. Here, of course, everything is not so neglected, but holy crap! These persistent guys who referring to the 14-page manual made me laugh a lot.

One thing is good: by the end of the thread, there appeared a brave rebel who just answered the question. They, like, named the required parameter for a FastAPI method's decorator, which is not supposed to be shown in the documentation. No links — could you imagine?

Not all heroes wear capes, I would say.

2023-09-24 work Swagger

Romania's Feature

Making a password recover function via SMS for our customer portal. Got to the Twilio documentation related to alphanumeric sender ID support in different countries; this feature allows you to send messages so that the recipient sees not the sender's number but something meaningful (a company name, for example).

The feature is regulated differently everywhere: in some countries it just works, but in others registration is possible or even required.

Well, let's take a look:

Screenshot

🤔

  • Portugal: yes
  • Puerto Rico: no
  • Qatar: yes (with registration)
  • Reunion: yes
  • Romania: yes (with registration) (but be afraid of Dracula)

I don’t know how else I can explain this cemetery.

UPD: Found the answer. Grave crosses mean you have to pay $700 to register.

To be frank, I like the explanation about Dracula much more.

2023-08-30 meanwhile work

New Fastimer

Released a new version of my console timer for intermittent fasting. I wrote this app about a year ago, when I was once again upset by the Zero application for Android: some very primitive functions (like viewing a specific interval) did not work. Oh my gosh, guys, you had one job!

The main difference between 1.3.1 and 1.2.3 is that the console menu has been cut to hell in favor of the good old arguments and options. The menu concept looks convenient only if an application has few features. However, as soon as you take a step forward, the need to answer a list of questions each time you need something starts to irritate you.

2023-08-23 done Python

Request Rheostat

I forgot to tell you that a couple of months ago I posted on GitHub an example of code that limits the number of requests per second that can be sent to some third-party resource from a 1C:Enterprise infobase.

The problem is solved through a constant that stores the date for the current second and the number of requests that have already been sent. Clients who run into a limitation are waiting. The queue is not guaranteed, but is more or less respected.

It can be useful for managing the load on an external system. For example, the cloud-based Bitrix24 requires not to send requests to it more than twice per second, and if you exceed it, it bans you.

2023-05-27 Bitrix

Do you speak English?

The repository login form of the current platform (8.3.22.1923, to be precise) launched with the English interface:

Login Form

You had one job, literally.

I heard some rumors that development of the Designer was stopped largely due to the monstrous amount of technical debt that slows down any new features. But here are interface glitches right on one of the first application windows! Curious how it got through the build tests.

Maybe they don't exist at all.

2023-05-14

Going Postal

Recently, I was working with vocabulary in an attempt to describe my latest adventures to an English-speaking friend and got to know about the colorful idiom “to go postal”. It means something like “go crazy with anger”; appeared somewhere between the 80s and 90s in the USA after a series of rather insane incidents in which postal workers went crazy and attacked people around, including colleagues and visitors.

The expression sounds funny at first glance, but the story behind the scenes is painfully gloomy. I think I will continue to use the good old “to go ballistic”. Literally, “get angry that strong so you become a rocket which lost control”. Or, to simplify, “explode with anger”.

By the way, there are similar rocket-like connotations in Russian, but for some reason they are about a more manageable cases. Mostly, they implies something like "the fire in the ass was so damn strong that the poor guy left Earth and successfully landed on Mars". Sounds a bit better than a simple explosion — you didn't completely waste the precious resource, at least :-)

2023-05-08 English

Pause()

An important detail: the CallPause method is not available in a client-server call; when a client calls a server method in which CallPause is called, the exception "Cannot call the CallPause method in a client-server call" will be thrown.

CallPause Method (RU)

What a strange restriction, to be frank. On the one hand, an experienced developer will not make an intentional pause in a client-server call anyway; on the other hand, whoever wants to make it makes it anyway (by checking time in a cycle, for example). Does security by obscurity worth the efforts?

At best, some junior will catch this exception, think “welp, it looks like I'm doing something wrong” and move in the right direction. However, putting the restriction on the platform for the sake of this case is like firing a cannon at sparrows. You know what? Let's implement a number limit as well — like, no more than 1000 pauses per session, otherwise users will suddenly think that the program is too slow :-)

2023-04-30

In a Pedantic Way

The daily award for the most philosophical code goes to the author of this elegant way to check that two boolean variables are not equal to each other:

If DataStructure.Property("AmountVATIn")
    And ((DataStructure.AmountVATIn And NOT SearchPriceIncludesVAT)
    OR (NOT DataStructure.AmountVATIn And SearchPriceIncludesVAT)) Then    
    Price = RecalculateAmountOnVATFlagsChange(Price, DataStructure.AmountVATIn, TabSectionLine.VATRate);
EndIf;

I'm thinking of adding something like “And Not (DataStructure.AmountVATIn = SearchPriceIncludesVAT)” here to spice it up with a subtle note of insanity.

2023-03-21 work code smell

Environmental Storytelling

I like to notice things in the world around me that clearly have a story behind them. In video games, this is called “environmental storytelling”: they don’t tell you the story directly, but if you look around, you can guess which gun was hanging on the wall and who fired from it.

For example, I recently celebrated the company's 10th anniversary with colleagues at a local golf club. Balls had to be sent flying from the second floor; there are no railings for obvious reasons, but a net is stretched in case someone loses their balance.

Photo from the club website to make it clearer.

Why are you talking about this, you ask? Well, there are warnings on the walls: jump into the net of your own free will and pay ten thousand dirhams. Recording this heroic leap of faith on camera is fine as well, just prepare five thousand more.

Do you feel the smell of a good history?

Another example: once flew to Turkey to rest and decided, just in case, to look through the rules of the airline (what can be taken on board, what can not). Among the list of items prohibited from being carried on board, I found “steel spear” and “steel flail” 😬

UPD: Another great example from somewhere on the Internet.

2023-03-19 meanwhile work

Slow down, I'm recording

Usually the idea of developing is simple: the faster it works, the better. For example, the more requests an application manages to execute per unit of time, the faster the task for which these requests are needed will be solved.

However, it also happens the other way around: you need to reduce the number of operations that a program is able to perform. Let's imagine we exchange data with an external service and it bans if we hit it with requests too often. For example: the cloud version of Bitrix24 requires sending requests to it no more than two per second.

Here is an implementation of such a slowdown, which I wrote last week. There is no queue support; the main solved problem is to execute as many requests as possible without going beyond the limit (taking into account the fact that requests can be made from different sessions).

2023-03-05 Bitrix done

REST service for Service Manager

This week, I developed a REST service to set up our service manager (this is a configuration for managing a 1cFresh instance). Deploying the development environment is a regular task for us, and every time the manager's database had to be tuned by hand: tweaking the storefront, changing application addresses, overwriting scheduled tasks, and so on.

The implementation was simple. Come up with a JSON structure, write a parser, find a code in the configuration, make it work by external call, and make sure you don't break anything. Routine work, in general, but I love to do such things from time to time: I mean, to look around and try to figure out which of the daily tasks is annoying enough.

This one is a good example. To be frank, setting up the Service Manager wasn't a problem (launching the app and fiddling with the settings), but it was a thing to pay attention & spend time to. What do we have now:

  1. There is a JSON file with all the settings;
  2. There is a REST service for its processing;
  3. There is a script that will put the first into the second;
  4. There is a pipeline that will do it all by itself.

In short, a boot was rubbing a leg, and now it isn't. Yahoo!

2023-02-25 work

Haul Trucks

Cars

The colleague grumbled that if you think like that, then the configurator will be Zhiguli, and the EDT will be Kama1 (this is an electric car that has been developed somewhere in the depths of KAMAZ for many years and still can’t gather strength and, finally, show the wonder to the world).

Well, I try to look at things with optimism. I think the platform and its IDE are such haul trucks. No one in their right mind rides them on household chores, but these beasts are irreplaceable on a cut!

2023-02-20

Earlier Ctrl + ↓