I find myself in the ironic position of being disappointed that a federal judge says Trump’s national non-emergency to redirect military funding to his wall is illegal. Not because I want him to built a massive monument to his racism and narcissism — I’d just as soon not have my tax money wasted on an ineffective reaction to an actual problem. But because I see the judicial precedent this would set — Bernie Sanders’ first day in office involves not ceremonial signing of legislation but rather the issuance of several national emergency declarations. Unhealthy conscripts hinder troop readiness, so there’s the Medicare for All national emergency. Uneducated conscripts hinder troop readiness, so there’s the tuition-free state University national emergency. The military has published studies about how climate change impacts troop readiness, but also our reliance on foreign energy sources (fuel for military vehicles) and foreign manufacturing (who is making the electronic components in military equipment, networks, communication devices, etc) … there’s the New Green Deal national emergency and the domestic manufacturing national emergency. Look at Egypt, Greece, etc — underemployment is a national emergency unto itself. And suddenly the near 700 billion dollar military budget is redirected to Sanders’ platform.
Git Log
Git log can be used to get a quick summary of the differences between two branches. The three dots between the branch names indicates you want a “symmetric difference”. That is the set of commits that are in the branch on the left or the branch on the right but not in both branches.
The –left-right option prefixes each commit with an ‘<’ or ‘>’ indicating which “side” has the commit. The –oneline option prints the abbreviated commit ID and the first line of the commit message.
Showing the differences between your local uat branch and the remote uat branch:
D:\git\gittest>git log –left-right –oneline origin/uat…uat
> 961f53a (uat) Merge branch ‘ossa-123’ into uat
> 803096b (origin/ossa-123, ossa-123) Added additional files
> cf9c419 Added initial code to branch
The top line is the most recent commit, the bottom line is the oldest commit that does not exist in both branches. I can see that the uat branch in my local repo is not missing anything from the remote (there are no commits with “<” indicating changes in the remote that do not exist in my local copy) but I have local changes which have not yet been pushed: two code commits plus the merge commit which incorporated the code commits to my local repo’s uat branch. The head of the local and remote ossa-123 branch are at the commit just prior to the merge, so on my local repo that branch has been fully merged into UAT and I just need to push uat up to the remote.
Additional options to enhance output:
–cherry-pick will omit any changes that represent the same changes in both branches (or –cherry-mark to mark those commits with an “=” flag)
–graph uses an ASCII chart to depict branch relationships.
* The three dots mean something different in git diff than in git log. In git diff, mean “what are the differences between the right-hand branch and the common ancestor shared by both the right and left-hand branches”.

Two dots in git diff mean is the differences that are in the branch on the left or the branch on the right but not in both branches.

In git log, two dots displays only commits unique to the second branch. Since commits and differences are not exactly the same thing, two and three dots don’t exactly have the opposite meaning between diff and log. But the meaning is not logically consistent.
Postfix IPv6 Loopback Failure
I needed to send email messages from a PHP form, and the web server at work uses Postfix. So … I’m getting Postfix set up to relay mail for the first time in a decade or two 🙂 I thought I’d just have to edit /etc/postfix/main.cf and add “relayhost = [something.example.com]”.
Nope. The service fails to start with nothing particularly indicative — just a [FAILED] status from the init script. Attempting to start Postfix outside of the init script is far more informative:
[lisa@564240601ac2 init.d]# /usr/sbin/postfix start postfix: fatal: parameter inet_interfaces: no local interface found for ::1
Turns out I’ve got to edit /etc/postfix/main.cf and tell it to use IPv4 only:
# Enable IPv4, and IPv6 if supported inet_protocols = ipv4
Roasting Pumpkin Seeds
Add enough water to fully cover seeds (2 cups, in my case)
Add a tablespoon of salt for each cup of water. Stir and let sit for a few hours (or overnight).
Preheat oven to 400 degrees F. Boil seeds in the saltwater for ten minutes, then spread across a baking tray.
Bake for 15 minutes, stir to flip seeds over, and make for 5-10 more minutes.
Apiary Thoughts
We made mead from local honey, and it’s got me thinking about having our own hives. In Ohio, you have to register your apiary every year — something to remember if we do get a hive! We’d need to get a hive — and misc equipment. Harvesting the honey seems pretty labor intensive — I like the Flow hives, but a grand for a hive is a lot and I expect there’s a lot of honey that remains in the hive. Which may not be a bad thing — I’ve certainly read about people feeding their bees sugar water over the winter. And I assume that’s from over-harvesting the honey.
Quilt tops — a shallow box on the top of the hive, with a wire mesh on the bottom, which is filled with straw or wood chips. It’s insulation.
Force majeure and the Township Solid Waste District
We attended a “Candidates Night” event last night where the two individuals on the ballot for a Trustee position spoke and took questions. Where most local elections don’t have much in the way of issues, this particular election may be a proxy vote for the single-hauler solid waste district because the incumbent was involved in the entire process and voted to establish a Solid Waste District that allows only one trash hauler. And indicated that she didn’t see anything wrong with the way the decision was approached.
There were two justifications provided for this decision — both financial. Individuals who have rubbish service will pay less for their service because the Township is essentially facilitating a bulk-purchase agreement. The company is going to drive the same number of miles but 100% of the houses will be their customer. The other stated motivation is reducing road repair costs. Not because the Trustees provided any evidence that rubbish trucks cause a significant amount of damage to roads (although I’ve been told it’s common sense that big trucks cause a lot of damage … there are four, I think, companies that collect rubbish in the area. Commercial rubbish collection is out of scope, so those companies are still going to be driving on some of the roads. What percentage of road damage is done by three rubbish trucks a week compared to vehicle traffic, delivery trucks, snow plows, freeze/thaw cycles? And that’s assuming the single hauler doesn’t need to increase the number of trucks/trips to collect all residential waste — which I doubt is true. We’re more likely to net remove one or two large trucks a week from the roads.). But when I asked what metrics would be provided to show that this cost savings would be realized, the incumbent candidate replied “I don’t think residents want to fund an expensive study about what roads needed repairs and how much it costs”. Which is a senseless non-answer — they’ve got a projected service department budget for next year. And hopefully the year after that. They’ve got historic actual numbers for decades. Take next year’s actual and compare it to the budget. How’s that compare to, say, the difference between last year’s actual and forecasted budgets?
But the oddest part of the night was when a resident asked about people whose existing contracts are a problem — either their current rubbish service will stop collecting trash a month before this single-hauler contract begins, their annual contract is up a month or three before the single-hauler contract begins and they’re not going to be able to renew, or their contract extends beyond the single-hauler start date. The first two scenarios are answered easily enough — the company that’s been chosen as the rubbish collector has agreed to start collecting “early” at rack-rate. So you “get” to buy service from the company you didn’t want at the price you didn’t want. The incumbent indicated that people whose contracts extend beyond the single-hauler start date won’t have to pay early termination penalties because of force majeure. Now maybe she’s actually seen residential contracts from each of the rubbish collectors that operate in this Township. We haven’t had rubbish service for years because we compost & recycle. The remaining trash (generally Styrofoam), we can drop off once a year at the county dump for like 1.50$. But in the contract we did have, force majeure was specifically protection for the trash hauler — they are not in breach for failing to collect rubbish in the middle of a hurricane, during a strike, etc. Courts tend to interpret force majeure clauses narrowly. If the hauler wants to push the issue … I doubt there’s a clause about government action freeing the resident from fulfilling their contractual duties. You’d be making an argument under common law contract doctrine.
But there’s no need to put yourself in a defensive position. The hauler will elect either to cease operation in the Township or incur penalties for continued residential rubbish collection. As a customer, you aren’t the one seeking to breach the contract. The hauler’s failure to act on their contractual duties may fall under a specific item within a force majeure clause. Or they may consider their duty voided under “frustration of purpose”. Call it “impracticability” because of the fines. It’s not like a resident needs to fight to compel their old hauler to continue their contractually-obligated duties that the hauler needs to defend their withdraw as a specifically permitted action. A resident needs the hauler to be the one who withdraws from the contract.
Testing Procedural Code with PHPUnit
You can use PHPUnit to test procedural code — in this case, I’m testing the output of a website. I have some Selenium tests for UI components but wanted to use the shell executor for functional testing. In the test code, you can populate the _SERVER and _POST (or _GET) arrays and simulate the web environment.
<?php
namespace phpUnitTests\CircuitSearch;
class CircuitExportTest extends \PHPUnit_Framework_TestCase{
private function _execute(array $paramsPost = array(), array $paramsServer = array() ) {
$_POST = $paramsPost;
$_SERVER = $paramsServer;
ob_start();
include "../../myWebSitePage.php";
return ob_get_clean();
}
public function testUsageLogging(){
$argsPost = array('strInput'=>'SearchValue', 'strReportFormat'=>'JSON');
$argsServer = array("DOCUMENT_ROOT" => '/path/to/website/code/html/', "HOSTNAME" => getHostByName(),
"SERVER_ADDR" => getHostByName(php_uname('n')), "PWD" => '/path/to/website/code/html/subcomponent/path');
$this->assertEquals('{}', $this->_execute($argsPost, $argsServer));
}
}
?>
Running the test, my web output is compared to the static string in assertEquals. In this case, I am searching for a non-existent item, nothing is returned, and I expect to get empty braces. I could use AssertsRegExp or or AssertsStringContainsString to verify the specifics of a real result set.
Deleting Git Branch — Local and Remote
Writing this down so I don’t have to keep looking it up after I merge my branch …
git push --delete <remote_name> <branch_name>
git branch -d <branch_name>
Docker for Windows: Using Built-in k8s
I just started using k8s built into Docker for Windows, but I couldn’t connect because the target machine actively refused the connection.
C:\Users\lisa>kubectl version
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.6", GitCommit:"96fac5cd13a5dc064f7d9f4f23030a6aeface6cc", GitTreeState:"clean", BuildDate:"2019-08-19T11:13:49Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"windows/amd64"}
Unable to connect to the server: dial tcp [::1]:8080: connectex: No connection could be made because the target machine actively refused it.
No idea — it’s all internal traffic, but I resorted to turning off my firewall anyway just to see what would happen. Nothing. Turns out I need a KUBECONFIG environment variable pointing to the config file
C:\Users\lisa>set | grep KUB KUBECONFIG=C:\Users\lisa.RUSHWORTH.000\.kube\config
Applied the yaml file and started the proxy
C:\Users\lisa>kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml secret/kubernetes-dashboard-certs created serviceaccount/kubernetes-dashboard created role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created deployment.apps/kubernetes-dashboard created service/kubernetes-dashboard created C:\Users\lisa>kubectl proxy Starting to serve on 127.0.0.1:8001
Working! Get the token from
kubectl -n kube-system describe secret default
And access the dashboard.
A reminder for myself — the totally not obvious package name for the kubeadm binary on the CHANGELOG link list is Node. Go figure!
Python f-strings
I’m accustomed to using variables directly in strings — most of my scripting experience was with Bash, Perl, and PHP. It’s something I have to think about when I would write Java or C++ code, and it’s one of the few things that struck me as a step backward in Python. This is basically the advantage that kwargs have over args, except changing a string common where changing a function definition is pretty rare.
I’ve taken to using the arg identifier numbers in the print statement.
>>> first=”Lisa”
>>> last=”Rushworth”
>>> print(“Hi {0}, you are {0} {1}.”.format(first, last))
Hi Lisa, you are Lisa Rushworth.
This allows me to append a new variable to the format argument list and use it anywhere in the string
>>> salutation=”Hello”
>>> print(“{2} {0}, you are {0} {1}.”.format(first, last, salutation))
Hello Lisa, you are Lisa Rushworth.
Python 3 introduced f-strings, which go beyond the functionality I was missing. You *can* use variable names within the string:
>>> print(f”{salutation} {first}, you are {first} {last}”)
Hello Lisa, you are Lisa Rushworth
You can have multi-line strings — notice that newlines aren’t being magically added. If you *want* newlines, add \n!
>>> strString = (
… f”{salutation} {first}, ”
… f”You are {first} {last} ”
… f”And I have more ”
… f”data down here”
… )
>>> print(strString)
Hello Lisa, You are Lisa Rushworth And I have more data down here
But you can also perform operations:
>>> print(f”{2 ** 3}”)
8
And use the f-string in classes
>>> class MyThing:
… def __init__(self, thing1, thing2, thing3):
… self.thing1 = thing1
… self.thing2 = thing2
… self.age = thing3
…
… def __str__(self):
… return f”{self.thing1} has 2 {self.thing2} and 3 {self.age}.”
…
>>>
>>> thingSample = MyThing(“Something1”, “Something2”, “Something3″)
>>> print(f”{thingSample}”)
Something1 has 2 Something2 and 3 Something3.
What if you need to have a literal curly brace?
>>> print(f”Hi {first}, this output needs a {{curly brace}}”)
Hi Lisa, this output needs a {curly brace}
