Sunday, October 18, 2020

Home network speed over my career

 




image.png





Two nice articles on database keys and joining

 https://codehaus.blogspot.com/2017/05/key-primary-and-foreign.html

https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join/38578#38578

A nice terminfo definition

TERM=xterm-256color infocmp >~/.terminfo/mhterm.terminfo


# 1. change name to mhterm
# 2. get rid of rmcup
# 3. get rid of smcup

TERM=xterm-256color infocmp |
    sed \
      -e 's/^#.*Reconstructed.*$/# xterm customized by marhar/' \
      -e 's/^xterm-256color.*$/mhterm|marhar customized xterm,/' \
      -e 's/rmcup[^,]*,//' \
      -e 's/smcup[^,]*,//' \
      >~/.terminfo/mhterm.terminfo

tic ~/.terminfo/mhterm.terminfo

export TERM=mhterm

Wednesday, October 14, 2020

BluBaby Wing Fabrication

Tony65x55 talks about BluBaby Wings:

A very short tutorial as to how to cold roll a Blu-Baby wing has been added to here:

https://www.rcgroups.com/forums/show...31&postcount=1

If you are unsure of the forming process this will amaze you. It's pretty easy.

Pic 1. After rolling the airfoil, flatten it a bit so the camber is the same for both. Make sure they mate together nice and straight. Block up the tips and you'll see where material has to be removed in order to mate them after the dihedral has been sanded into the wings.

Pic 2. After the dihedral has been sanded in, glue 'em together. I normally use a bead of hot melt. After it has completely cooled (dried?) I take a thin bead of PU glue and rub it into the joint. When it expands it assures complete adhesion. I put a half width strip of duct tape, preferably white or black, across the top of the joint for looks and strength. It also assures the PU glue doesn't ooze out the top of the wing. Under the wing, I cut a popsicle stick halfway through, bend in the dihedral and hot melt it to the wing at the 33% chord mark. This is also the CG point. Lastly, I run a strip of fiber reinforced tape across the bottom of the wing, tip to tip. This tape is brute strong a gives a great deal of strength to the wing without adding any appreciable weight.

NOTE: This plane was designed as a primary trainer and was designed around the GWS IPS motor system. If you are goiing to put a powerhouse motor in it, additional bracing may be needed. On the Blu-Baby Park (GWS 350-C), I used bamboo wing struts. 

https://www.rcgroups.com/forums/showpost.php?p=7423038&postcount=75


Friday, October 2, 2020

MacOS Keychain Command Line

 # add a password
security add-generic-password -a {Account} -s {Service} -w {Password}
# retrieve a password
security find-generic-password -a {Account} -s {Service} -w

example:
set smtp_pass = `security find-generic-password -a mailsync -s bob@example.com -w`

HT: TIL: macOS keychain command line - Rys Sommefeldt

Friday, June 19, 2020

Why I Love OpenSCAD

I just made a knob and it struck me what a quick and easy job it was.

The central shape is a cylinder of height 20mm and diameter 50mm.

            cylinder(20, d=50);



Two smaller offset cylinders are the grips.

            cylinder(20, d=50);
            translate([50,0,0]) cylinder(10, d=30);
            translate([-50,0,0]) cylinder(10, d=30);



We wrap the pieces into a completed shape with hull().

        hull() {
            cylinder(20, d=50);
            translate([50,0,0]) cylinder(10, d=30);
            translate([-50,0,0]) cylinder(10, d=30);
        }



And add a screw-hole with difference().

    difference() {
        hull() {
            cylinder(20, d=50);
            translate([50,0,0]) cylinder(10, d=30);
            translate([-50,0,0]) cylinder(10, d=30);
        }
        cylinder(20, d=8);
    }


Friday, September 20, 2019

Expanding the creative envelope: Two lessons from Jazz.

I am frequently asked where do I come up with my new ideas?  To be honest, I'm not exactly sure... but I have thought about the process that I believe makes it easier for ideas to suggest themselves.  I think that puts this post in the "creative thinking" bucket.

Two key ideas seem intermingled and both interestingly come from the jazz world. 

This text which appears in the intro background of the 1997 Japanese Anime series Cowboy Bebop. It's never mentioned or referenced in the show, or even clearly shown.  I had to search the Internet to find the exact words.  If you're enjoyed the Ken Burns Jazz documentary, you will recognize the reference to Minton's Play House. BTW, The intro itself is just 90 seconds long... it's worth a listen.

We will play without fear of risky things.

Once upon a time, in New York City in 1941... at this club open to all comers to play, night after night, at a club named "Minston's Play House" in Harlem, they play jazz sessions competing with each other. Young jazz men with a new sense are gathering. At last they created a new genre itself. They are sick and tired of the conventional fixed style jazz. They're eager to play jazz more freely as they wish then... in 2071 in the universe... The bounty hunters, who are gathering in the spaceship "BEBOP", will play freely without fear of risky things. They must create new dreams and films by breaking traditional styles. The work, which becomes a new genre itself, will be called... COWBOY BEBOP 


Don't Play the Butter Notes

The second thing is a story by Jazz great Herbie Hancock, where he tells about the words Miles Davis said to him that allowed him to change the shape of Jazz to this day.  The whole clip is worth listening to, but the most important part is at 03:37 if you're in a hurry.



The key point of the Hancock story is when Miles Davis told him to "stop playing the butter notes." which Hancock counter-intuitivel interpreted as advice to remove some of the most important notes in the chord, the third and the seventh.  If you've ever had music lessons, you know those are some of the key notes that define the  "flavor" of the chord, and it's pretty hard to imagine what the chords would sound like without them.

But by removing those notes, Hancock discovered he had room for different notes, ones that would have been in conflict if he had kept the third and seventh.  Now, because they were gone, it was possible to weave many other harmonies to the tune.

We see a similar thing when playing with a Rubik's cube... it's easy to solve the first face, but it's impossible to make any further progress until you are willing to discard this apparent progress as you work on the next steps.

Takeaway One: Hancock progressed because he was willing to discard the most important notes in his chord and see what happened.

The three sections of the Bebob text all relate to the same theme: seeking the freedom to create a new life or style. For the musical pioneers, the futuristic bounty hunters, and the self-referencing creators of a new literary work, success is not guaranteed. That's why they have to acknowledge the risk and push forward "without fear."

Takeaway Two: Progress involves risk, and you have to push forward without fear.

Boiling this down to some practical questions that I regularly ask myself:

  • What can I leave out of my current thinking? See what fills in the resulting gaps.

  • How have my circumstances changed that might allow me to discard a previously useful practice?  Those are the things that will hold you back.

  • What ideas and precepts do I hold that have been valuable to me, but that might be blocking forward growth?  How do these differ from things I shouldn't discard?

  • Do I have the courage to discard these things and face a new future?
Practical Advice
  • In computers, eras are surprisingly short.  Be prepared.

  • If an idea seems "dangerous", understand it to the point you can advocate for it.  Explain the different presuppositions that would make it the idea useful.

  • Pushback is valuable; learn from it, incorporate it, and don't be discouraged.

  • "Play without fear" even when you're afraid.  That's called courage!

  • Regularly review your "butter notes".

Monday, July 17, 2017

OpenSCAD -- calculating a chord segment

Given chord length c and segment height m (this is called a "sagitta"),

radius = (m^2 + (c^2)/4) / (2 m)

In OpenSCAD:

c=20;
m=5;
radius=(pow(m,2) + pow(c,2)/4)/(2*m);



https://softsolder.com/2013/08/02/making-finger-grip-dents-the-chord-equation
https://en.wikipedia.org/wiki/Circle#Sagitta

blogodex = {"idx": ["openSCAD", "circle"]};

Wednesday, May 10, 2017

Keys, Primary and Foreign

Welcome to the Bank

Suppose we have an oversimplified banking system, with two tables.

create table balances(name string, balance number);
create table transactions(tid number, from string, to string, amount number);

This allows us to populate a table of people with balances, and transactions where people give money to each other.

    balances
    name | balance
    -----+--------
    ann  | 200
    bob  | 150
    leo  | 300

    transactions
    tid | from | to  | amount
    ----+------+-----+-------
    1   | ann  | bob | 25
    2   | bob  | leo | 50

We can imagine traversing the transaction table something like this pseudocode:

    for (from, to, amount) in select("select from,to,amount
                                        from transactions
                                       order by tid")
        begin transaction
           update balances set balance = balance - amount where name = from;
           update balances set balance = balance + amount where name = to;
        commit;

(note that sql implementations all vary slightly in how tables and indexes are creates.  Everything following is pseudocode.)

Some Data Problems?

Here's a couple of problems we've got in the present system.

  1. We can have empty (null) fields.  For example, a transaction of insert (3,bob,NULL,NULL).
  2. We can have duplicate people in the balance table.  Note that it's OK if balances are duplicated (you and I can have the same amount of money!) but each person must be unique.
  3. We are going to be performing lookups keyed by transactions.tid and balances.name.  We better make that efficient if we're going to grow to be a bank with millions of users and transactions!

Some Data Solutions

1. Let's specify all fields that are required.

    create table balances(name string not null, balance number not null);
    create table transactions(tid number not null, from string not null,
                              to string not null, amount number not null);

Now a transaction will fail if we insert a row with a null column.  This  is nice, because now our code can safely assume we have good non-null data).

2. Specify we can't have duplicate names.

    create table balances(name string unique not null, balance number not null);

This will cause an error if we ever

    insert into balances(name, balance) values('bob', 100);
    insert into balances(name, balance) values('bob', 200);

3. Create some indexes on our key search columns.

    create index balances_name_ix on balances(name);
    create index transactions_tid_ix on transactions(tid);

Primary Keys

When we look at our tables, we notice that each has a column which serves as the main identifier of a row.

  - balances are "owned" by name
  - transactions are identified (and ordered) by tid.

We notice three things about these columns.

  • they should never be null (because they identify the row)
  • they should be unique (because it doesn't make sense for them to be dupes)
  • practically, they should have an index (because we usually use them in where clauses).

The concept of a table having a main identifying column, and that column having the three attributes just listed, is so common that we give this a name:  That column is the primary key, and can be specified as such.

    create table balances(name string primary key, balance number not null);
    create table transactions(tid number primary, from string not null,
                              to string not null, amount number not null);

Declaring a column to be a primary key automatically sets the three things we noticed earlier.

  - primary keys are NOT NULL
  - primary keys are UNIQUE
  - there's an index automatically created for the PK

In addition, via notation we've specified that the row's "identifier" is a particular key... we don't have to guess or infer this information.

Foreign Keys

Let's consider a row in the transactions table:

    (1, "ann", "zoo", 50);

If we run this throught the pseudocode above, everything will work and no errors will be reported.  But there's a very big problem.  This statement is correct,

    update balances set balance = balance + amount where name = 'zoo'

but it loses the $50 ann is trying to transfer, since there's no row in balances where name is 'zoo'.

We can solve this in the database by specifying that transactions.from and transactions.to refer to balances.name.  Note that semantically this removes the requirement that we declare transactions.from and transactions.to as NOT NULL, since they are required to match balances.name.

    create table transactions(tid number primary,
                              from string references(balances.name),
                              to string references(balances.name),
     amount number not null);

With this in place, this insert will fail:

    insert into transactions values(1, 'ann', 'foo', 100);
    *** ERROR: foo does not exist in balances(name)

and this delete will fail:

    delete from balances where name = 'ann';
    *** ERROR: can't delete row with dependencies

There are various options when creating foreign keys, such as ON CASCADE DELETE.  In this case,

    delete from balances where name = 'ann';

would cause this statement to be implicitly executed as part of the transaction.

    delete from transactions where from = 'ann' or to = 'ann';

Caveats

Note that a lot of systems might document the foreign key relations are, but not enforce them in the database, relying instead on programming logic.  Sometimes this is done for efficiency (e.g. many inserts into the transactions table -- if you verify from and to are correct, you don't want to pay two lookups penalty on each insert).

A Common PK/FK Idiom

Splitting a potential Fat table into several smaller tables.  Sometimes it's for ease of use, sometimes it's for other reasons.  For example

    create table master_users(uid, Name);
    create table billing_info(uid, credit_card, expires, ...);
    create table contact_info(uid, address, email, phone, ...);
    create table lawsuit_info(uid, ...)

We might be legally required to protect lawsuit_info and not make it visible to people who can see contact info.

In any case, we would make uid a PK in all four tables, allowing us to

    # get everyone
    select m.name, b.email
      from master_users m, billing_info b
     where m.uid = b.uid;

    # get one person
    select m.name, b.email
      from master_users m, billing_info b
     where m.uid = b.uid and m.uid = 123;

And we could optionally add FK relationships from *_info.uid to master_users.uid.

Thursday, November 24, 2016

Arduino Stepper with ULN2003 driver

// stepper1 -- repeat 1 CW and CCW revolution
/*
https://arduino-info.wikispaces.com/SmallSteppers
5v 28YBJ-48 Stepper Motor with Gear Reduction
ULN2003 driver board
*/

#include

// internal motor steps per revolution in 4-step mode
#define STEPS_PER_MOTOR_REVOLUTION 32

// steps per OUTPUT SHAFT of gear reduction
#define STEPS_PER_OUTPUT_REVOLUTION (STEPS_PER_MOTOR_REVOLUTION*64)

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4  and then the pins entered
// here in the sequence 1-3-2-4 for proper sequencing
Stepper s(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);

void setup()
{
  s.setSpeed(500);  // 700 good max?
}

void loop()
{
  s.step(2 * STEPS_PER_OUTPUT_REVOLUTION);  // CW 1 turn
  s.step(-STEPS_PER_OUTPUT_REVOLUTION); // CCW 1 turn
  delay(500);
}

Friday, November 4, 2016

Perfect SSL Score with Go

Peter Lambert makes it look easy!

https://blog.bracelab.com/achieving-perfect-ssl-labs-score-with-go
https://gist.github.com/denji/12b3a568f092ab951456#perfect-ssl-labs-score-with-go

Arduino Encryption

I've been looking at encryption libraries that would run on an Arduino.  This looks like something worth looking into.
This library contains a cryptographic pseudo-random number generator, cryptographic hash and message authentication code (MAC) functions, can perform symmetric-key authenticated data encryption, and general-purpose functions for timing-safe comparison and wiping data from memory.
https://hackaday.io/project/8244-arduino-spritz-cipher-library
https://github.com/abderraouf-adjal/ArduinoSpritzCipher
https://people.csail.mit.edu/rivest/pubs/RS14.pdf