HN user

spellcard199

57 karma
Posts0
Comments19
View on HN
No posts found.

Some weeks ago I searched for a more general solution that doesn't depend on the compositor and doesn't need root (i.e. an xkill replacement), but I didn't find one.

As a frequent user of xkill I was surprised by that too, but I remember reading somewhere that making a terminal application kill another application's window is not allowed by design. Reusing a sibling commenter's analogy, it's kind of like some javascript functions in the browser can only be triggered by user actions for security reasons.

The compositor, however, is allowed to kill the windows it's showing. So if you want to kill a window, you can ask the compositor to do it for you. Gnome, KDE [0], sway [1], etc.. each expose this functionality in a way that differ between each other.

[0] https://www.reddit.com/r/kde/comments/1242w2e/wkillsh_an_xki...

[1] https://www.reddit.com/r/linuxquestions/comments/ufw7tj/is_t...

Under Wayland with Gnome (it's gnome-specific), I recently learned you can kill windows by using Looking Glass:

  // 1. Open looking glass: Alt+F2 > lg
  // 2. Use picker to pick window (button on the top left corner).
  // 3. Now an object r(0) of type MetaSurfaceActor is available in the
  //    gjs console (or some other number if you've already used it).

  // To get pid:

  r(0).get_parent().get_parent().get_meta_window().get_pid()

  // To kill window and process:
  
  r(0).get_parent().get_parent().get_meta_window().kill()
Reference for what those .get_parent() refer to: https://gitlab.gnome.org/GNOME/mutter/-/tree/fc1de744/src/co...

Hello. I'm just a (bad) med student and I'm not qualified to make any diagnosis, but I think the clinical picture you have reported warrants further investigations and I wanted to share my thoughts while I was reading your post.

In the demographic of woman of child-bearing age the coexistence of more than one autoimmune diseases is not uncommon. Occasionally, there are even combinations of several of them [1]. As you've written, the manifestations you have reported may or may not be caused by one or more autoimmune diseases, but the ones that tipically keep autoimmune/rheumatologic origin in consideration even when labs are negative are the partial spinal fusion and the arthritis [3][2].

According to every test they run on her, there appears to be nothing wrong

Does it? We have:

- clinical picture strongly suggesting some rheumatologic disesease: inflammation and rapid onset arthritis are typical, but DVT, random bleeding may also be linked.

- radiographic evidence of spinal fusion.

And that's exactly how (eg) Ankylosing Spondylitis has been diagnosed classically (i.e. when MRI was not an option) [4]. More generally speaking, as the name suggests, the diagnosis of most Seronegative Spondyloarthropathies is based more on clinical than laboratory criteria [3]. For how I understand it, ideally AS would be diagnosed before spinal fusion happens, but when it's present and there isn't a more likely explanation AS would be at the top of the differential diagnosis.

Another thing that came to my mind when reading DVT, bleeding, vision loss was that these are more typically seen together in of some kind of vasculitides, hence why I mentioned above an the possibiity of multiple autoimmune diseases, but these could also be explained by anything altering Virchow's triad.

There's no explanation for the temporary blindness, the rapid onset arthritis, the partial spinal fusion, the diverticulitis, the random bleeding,

That sounds somewhat strange. While for temporary blindness, diverticulitis and DVT the cause may already be gone by the time the patient arrives at observation, at least for rapid onset arthritis, spinal fusion and random bleeding I think a diagnosis of the cause should be made.

The reason why rheumatologic diseases should be diagnosed is that if left untreated there will be periods of remission, when nothing happens, and periods of activity, when irreversible damage accumulates. Another reason to diagnose rheumatologic diseases is that they may themselves be manifestations of some other condition (e.g. rheumatologic paraneoplastic syndromes). We don't know if your wife actually has a disease, it may be not, but that's not a risk a doctor would leave to chance. It's just standard practice.

As I've already written I'm not a doctor, but if I may give you my advice anyway I would say your wife should go and see a rheumatologist.

There's no one who either wants to or is qualified to look.

If I were in you, at this point I would go to some known research center with maybe a university department or ward.

[1] [Coexistence of Axial Spondyloarthritis, Systemic Lupus Erythematosus, Sjögren’s Syndrome and Secondary Antiphospholipid Syndrome: Case Report](https://dergipark.org.tr/en/download/article-file/1615538)

[2] [Approaching the Patient with "Joint Pain" - CRASH! Medical Review Series ](https://www.youtube.com/watch?v=sfKWNeAywak&t=195s)

[3] [Seronegative Spondyloarthropathies - CRASH! Medical Review Series](https://youtu.be/hvQkROf5rsQ?t=377)

[4] [Progression of Spinal Fusion in Ankylosing Spondylitis](https://clinicaltrials.gov/ct2/show/NCT00085995)

As you can see I am a fan of both your product and the philosophy behind it, so thank you for your work. If I was interested in working just on software diagrams.net would be somewhat of a dream job for me, however, currently my life plan is to finish my last years of med school (after being stuck for ~20 years) and then possibly do something related to both software and med at the same time. Thanks for the offer anyway, since it came from you I admit I have really appreciated it.

I agree on the graphical editor. Before customizing it to my needs there were several behaviors that I found quite tedious.

Since it may be of interest I'll add some notes.

You can get a console also in the desktop app if you launch it from a terminal adding --remote-debugging-port=..., then opening http://127.0.0.1:<port> from a chromium-based web browser.

A couple of useful functions that allow to listen to events are graph.model.addListener and graph.selectionModel.addListener. They are documented in the mxGraph api page.

You can make your functions persistent between sessions by putting your code in a javascript file, clicking from the desktop app on Extras > Plugins > Add > Select File... Then restart the app. In the web app "Select File..." is replaced by "Custom..." and the file should be some reacheable url. The javascript file can contain arbitrary javascript code, doesn't need to have a specific format.

Finally, to customize the ui actions, keybindings and menus without touching the various event listeners, this answer on stackexchange [1] from user holroy is what initially guided me in the right direction.

[1] https://webapps.stackexchange.com/a/82379

I 'm an heavy user of diagrams to take notes while learning topics in biology and medicine. I think the most interesting feature of diagrams.net is its extensibility, which is not frequently mentioned. If you run in the javascript console...

    var editorUi;
    Draw.loadPlugin(app => editorUi = app)
    var editor = editorUi.editor
    var graph = editor.graph
... then you can automate changes to the diagram using mxGraph's api [1] on the `graph' variable from the console.

Around this plugin mechanism I wrote some dirty hacks for personal use to make the editor behave more to my likings [2] (some features stopped working with recent versions of the desktop app), and an even dirtier Emacs mode for editing labels and having the js REPL available directly from Emacs when I need to run some code to fix my diagrams programmatically [3] (based on Indium [4] + the fact that electron apps can be launched with --remote-debugging-port=...). It's not pretty, but works enough for me, and it's only thanks to the customizability that diagrams.net allows.

[1] https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGr...

[2] https://gitlab.com/spellcard199/drawio-plugin-eight-droves-o...

[3] https://gitlab.com/spellcard199/emacs-drawio

[4] https://github.com/NicolasPetton/Indium

One thing that made it difficult to me was that I didn't explicitly realize for a long time that there were two things to understand: what a monad is and why they are useful. Most explanations tell why it's useful, but it really clicked for me when I read through the book "Haskell Programming from First Principles" (Julie Moronuki, Christoph Allen) [1] and got to the monad chapter, which if you read the previous chapters explains really clearly what a monad is.

The way I understand monads: some data structure plus 2 functions, "return" and "join":

- "return": wraps something with the data structure. (no relation with the return keyword you are used to in most languages)

- "join": joins 2 layers of the _same_ data structures into one.

And that's it. It's just that simple what a monad is: in java it would be an interface with just these two methods.

Examples:

- "return" for List: takes a value and returns a List containing just that value.

- "return" for Maybe: takes a value and returns Maybe value.

- "join" for List: takes a List of Lists and returns a flattened List (2 outer layers joined).

- "join" for Maybe: takes Maybe Maybe value and returns Maybe value.

I think what makes these functional programming concepts hard to grasp most of the times is that communicating the boundaries of abstract concepts is hard in general, even if the concept itself is really simple, like a monad can be for a programmer.

As for why monads are useful, the explanations you can find online give a lot of examples. Just think of all the times you may have used flatmap for arrays: that's just map followed by the "join" for arrays, which is sometimes called flatten. The other operators you see used in haskell, like "bind" (>>=), can be derived from "join" and vice versa and are just conveniences to write code with less noise, like flatmap is.

Recap: monad is the name of the concept for things that have a "join" and a "return" functions defined. Basically "join" is the distilled concept of what a monad is.

[1] https://haskellbook.com/

(edit: formatting)

Racket's graph library can do everything jgraphx can do

What I need is to make a diagram from a file produced by diagrams.net without me writing the parser (JGraphX can already parse diagrams.net's xml), show me a window where I can select and adjust elements by hand, transform the diagram programmatically in a language where I have both type-checking and good completion for (eg) the selected objects, export back to diagrams.net's format. Occasionally I want to extend the already interactive window myself. I also evaluated Typed Racket before picking Kawa and the JVM, but JGraphX was just a more appropriate tool for this specific workflow.

There's also this (and others) for selenium

I remember finding that, and I counted it as a subset of Selenium's functionality rather than equivalent.

I agree on the sentiment on Racket though, as for the language itself Java was a second choice for me. What eventually convinced me to invest in it was that I could always call what I had already written from other languages on the JVM (mainly Scala and Kawa, which also happen to have decent repls) without writing any glue code.

If Racket had packages functionally equivalent to the ones on the JVM that I can't live without (Selenium, JGraphX, ...) I would start learning it right away. However sticking to the JVM and Kawa I get a vaguely similar typed/untyped experience except for the un-lispyness of Java. Usually when I write a script I make a new Java project that also pulls the dependencies and then embed Kawa (or jshell/ammonite jupyter server) for interactivity. Between the pom.xml and the code itself embedding Kawa (or jshell/ammonite) in a java program is like 10 lines at most.

After trying Typed Clojure, liking it, but giving it up because of Clojure's GPL-incompatible license, I got interested in Kawa Scheme because it has some rudimentary form of type checking. For example, this produces warnings:

  (define (f1 x::String y::String) (x:concat y))
  (define (f2) (f1 3 3))

  ;; /dev/tty:3:19: warning - type integer is incompatible with required type java.lang.String
  ;; /dev/tty:3:21: warning - type integer is incompatible with required type java.lang.String
  ;; /dev/tty:3:15: warning - cannot convert literal (of type gnu.math.IntNum) to Type java.lang.String
  ;; /dev/tty:3:15: warning - cannot convert literal (of type gnu.math.IntNum) to Type java.lang.String
Unfortunately it does not support fully static type checking nor generics, otherwise it would be my favorite scripting language hands down.

As for type checking Elisp, Elsa[1] seems an interesting project and I hope it becomes a stable option. On the other hand I wonder if in future type checking could also come from gccemacs[2], since one of the "long-term improvements" may be "better compile time warning and errors relying on the propagation engine".

[1] https://github.com/emacs-elsa/Elsa [2] https://akrl.sdf.org/gccemacs.html

Edit: grammar.

I have a question. I know nothing about ML and neural networks so I'm going to excuse myself if the answer to this may be obvious.

The specificity of CT when interpreted by humans is reported to be <56% [1]. The specificity for this model seems to be around 80%, which looks too good to me (I did 79/(79+19)=0.8, taking the numbers from the table at the bottom in OP).

Is it that the non-Covid-19 scans in the training data were easier to recognize than the ones doctors see every day or is the model so much better than humans at recognizing non-Covid-19 cases? If it was the latter, the reduced sensitivity (human: 96% [1], model: 85%) would not look bad at all, right?

[1] https://pubs.rsna.org/doi/full/10.1148/radiol.2020201709

When I finally got Bayes Theorem I thought it says something obivious in unfamiliar terms.

What made it click for me was realizing that bayesian networks are a mini-language and the Bayes theorem is much more easily explained visually than with formulas. I think teachers should start with telling the correspondence between them and probability terminology.

Here's how I would explain it.

----

In a bayesian network nodes are events, arrows are probabilities.

When you traverse a path made of successive arrows you multiply the probabilities of the arrows you encounter along the path.

When there is more than one path to get from A to B and you want to know the probability of getting from the former to the latter, you sum the probabilities obtained from the various paths.

When you say "probability of A" it's like saying: sum of the paths that get to A.

When you say "probability of A and B" it's like saying: sum of the paths that include both A and B.

When you say "conditional probability of B given A" it's like saying: starting from A, sum of the paths that lead to B.

----

Let's do a simple application. This is a tree that doctors should find familiar and from which i understood it.

     /T+
  D+/
   /\
  /  \T-
 /
 \    
  \  /T+
   \/
  D-\
     \T-
    
Starting from root, at the first bifurcation we have: probability of having a disease or not. At the second bifurcation we have: probability that a diagnostic test tells either "positive" or "negative".

Usually doctors can estimate the values of the single arrows of this tree.

Let's say I told you: what's the conditional probability of having a positive test given the patient has the disease? Given what we said, you just put your pencil on D+ and follow the path to T+: just 1 arrow, no need to multiply (it's called the "sensitivity" of the test).

What's the probability of having a positive test randomly extracting a person from population? Since we don't start with a patient that has or not a disease, we put our pencil on root. There are 2 ways of getting to a T+: root-->D+-->T+ and root-->D- -->T+. As we said above, while following each of the paths we multiply the arrows we encounter and then we sum the result of the 2 paths.

And finally: what's the probability of our patient having the disease given that the test says "positive"? We said we have 2 ways to get a positive test, but in only one of these ways our patient really has the disease, so we just divide the probability given by the only path that contain both D+ and T+ by the probability given by all paths that lead to T+. We are just saying that true positive are a fraction of all positives (seems obvious to me?). Numerator is the only "test is positive and it's true" path. Denominator is the sum of all "test is positive" paths.

Well, guess what we just did:

P(D+|T+) = ( P(T+|D+) P(D+) ) / P(T+)

(Additional intuition: another way to see it is that what we did corresponds to mapping the tree we started from to a flipped one in which the first bifurcation is T+/T- and the second one is D+/D-)

---- TLDR ----

I completely agree with the others who say:

  - learn elisp instead of learning "emacs"
  - if you want to memorize something, just learn the name of the command: if you use it very often then learn/define a keybinding for it
---- part 1: I'm happy I've learned elisp in the last year

People complain about memorizing emacs keybindings, but most of the time I just call the command name with M-x command-name. Only if I find myself using it often I bother memorizing or setting a keybinding for it.

As for why I use emacs, I started using it for org-mode, which I considered it's only killer feature at the time. Since 1 year ago I started learning elisp and I think only now I can see what's the whole point of emacs.

In just 1 year of (beginner-level) elisp I wrote 75 files containing elisp functions to help myself with dozens of tasks that comprise:

  - move/mirror parts of ascii diagrams
  - automate some tasks just clicking on custom org-mode links
  - wrap ammonite-term-repl to get Ammonite completion for scala scripts [1] [2]
  - add rudimentary support for kawa scheme to geiser (my first pull request ever (still waiting for response))
  - control video player from within emacs while I'm writing subtitles
---- part 2: you can have different emacs configurations

Another common complain is that emacs tends to become slower as you add more and more packages. As a spacemacs user, I noticed that too. For this reason when I don't need spacemacs goodies I use multiple, different emacs configurations (with evil-mode though).

This is how I do it:

1 - Make a new ".emacs.d" user directory somewhere

2 - Make a new "init.el" user file inside it

3 - Add to the beginning of init.el :

    (setq user-init-file (or load-file-name "path-to-init.el"))
    (setq user-emacs-directory (file-name-directory user-init-file))
4 - Call emacs with:
    emacs -Q --load "path-to-init.el"
That's it.

You could achieve the same result using cask, which would be more elegant imo, but takes a couple of seconds more to start.

---- part 3: use elisp to call other languages

As for elisp, once you have learned enough of it (not much), if you are determined not to use it, there are different ways to call other languages from it:

  - clojure through cider plus clomacs
  - common lisp through slime
  - shen through shen-elisp [3]
  - different compiled languages through dynamic modules:
    - C  (example at [4])
    - go (example at [5])
  - ... many others I haven't investigated...
Just out of curiosity, I explored the shen-elisp path. I tried a whole week to see if I could replace it with shen-elisp. At the end of the week I learnt how to call elisp from shen-elisp and shen-elisp from elisp... and the fact that every time you restart shen-elisp you have to re-declare types. However I abandoned the idea for 2 reasons:
  - Plain elisp is faster: I don't know the implications
  - I wanted to focus on elisp so I can contribute better to other elisp projects
---- references
  [1] https://github.com/zwild/ammonite-term-repl
  [2] https://github.com/spellcard199/ammonite-term-repl-completion
  [3] https://github.com/deech/shen-elisp
  [4] http://kitchingroup.cheme.cmu.edu/blog/2017/07/08/Adding-numerical-methods-to-emacs-with-dynamic-modules/
  [5] https://mrosset.github.io/emacs-module/

I'm just writing an emacs process-output reader on top of https://github.com/zwild/ammonite-term-repl to get Ammonite's completion directly in emacs buffers. Of course it's a (very) dirty hack compared to something like a notebook or nREPL, but for my needs a notebook is too heavyweight and there isn't a nREPL implementation for ammonite/scala.

I started writing this so I could at the same time learn some elisp while writing something I would use in future. I'm still trying to figure out things (git forkflow, elisp, scala) but it already seems to work most of the times.

Link: https://github.com/spellcard199/ammonite-term-repl-completio...