Saturday, March 28, 2020

Captain Con And Reflections On Convergence

I just got back from Captain Con yesterday and it was an absolute blast. I haven't been to a convention for about 4 years, and I was extremely excited to get back to one.  This was my first Captain Con and I had only heard good things from my friends who've been going the past few years.

It definitely lived up to the hype and was exactly the kind of con I'm comfortable attending - not too big or too small.  It was mainly a Warmachine convention with roughly about 100 players attending, though there was a sizable (over 32 players!) Guild Ball event run by the Liberty Guild Ball group that plays at Showcase Comics in Media PA.  There was also a AoS tournament but that only had 8 players, where as Monsterpocalypse pulled in 16 players.

Add in role playing, demos, and everything else and we're looking at about 200 people which is just the right size in my view.



What to play?

All of the people I traveled/roomed with were all in on Guild Ball and I was completely hyped for Warmachine.  I was set to play in Champions on Friday for WM, and since I didn't get on a team for the New England Team Tournament and was scheduled to play Guild Ball on Saturday.  I put my name in for the waiting list and managed to get on a team with some great guys from Montreal and got to play Warmachine all weekend.

On one hand I was a little sad to only play a single Guild Ball game against a friend in a pickup game, but on the other I was just completely hyped to play WM.

The Beatings Will Continue Until Morale Improves

Ironically I'm still hyped to play WM and Convergence, despite the fact that I lost nearly all of my games. The first take away from this is that I need more experience. My old habits and experience from when I was playing more regularly don't hold up, and the rust didn't just shake off. I haven't been able to get more than 2-3 games a month the past three months because of work/family and it showed really hard in my play at the con. I am far more out of practice than I realized.

There were a few games where I could have easily won had I remembered to spawn a servitor off my Axiom to contest scenario, or didn't rush through a turn after a phone call from my kids because my clock was low and I failed to position my shield guards properly - but even where I didn't really have fun (I got bottom of turn 1 assassinated by Sloan where he basically had to go for it otherwise he'd have a hard time on attrition), I learned WTF I should do in that game properly.

Nearly every time I've played Orion before this weekend it was into a melee list, never into a gun list and so I wasn't properly prepared.  On the plus side, the guy who got me is someone I've listened to on podcasts quite a bit and when he heard I had lost one of my casino dice, he ended up giving me some of his that were the same color. Super nice guy and shout out to Dan Riker and the Battle Driven folks.

So I took a bunch of beatings, but morale is improving. I ran the following lists:

Champions

Convergence Army - 75 / 75 points
[Theme] Clockwork Legions

[Lucant 1] Father Lucant, the Divinity Architect [+28]
 - Corollary [6]
 - Diffuser [6]
 - Diffuser [6]
 - Galvanizer [5]
 - Galvanizer [5]
Enigma Foundry [0(4)]
Enigma Foundry [0(4)]
Enigma Foundry [0(4)]
Enigma Foundry [4]
Frustum Locus [4]
Clockwork Angels [5]
Obstructors (max) [11]
Obstructors (max) [11]
Reciprocators (max) [18]
Reductors (min) [8]
 - Transverse Enumerator [3]
Reductors (min) [8]
 - Transverse Enumerator [3]

Theme: Destruction Initiative
4 / 4 Free Cards     75 / 75 Army

Iron Mother Directrix & Exponent Servitors - WJ: +27
-    Iron Mother Directrix & Exponent Servitors Cont.
-    Corollary - PC: 6
-    Prime Axiom - PC: 38 (Battlegroup Points Used: 27)
-    Mitigator - PC: 7
-    Mitigator - PC: 7

Transfinite Emergence Projector - PC: 19
-    Permutation Servitors
Transfinite Emergence Projector - PC: 19
-    Permutation Servitors

Algorithmic Dispersion Optifex - PC: 2
Elimination Servitors - 3 Elimination Servitors: 0
Elimination Servitors - 3 Elimination Servitors: 0
Elimination Servitors - 3 Elimination Servitors: 0
Attunement Servitors - 3 Attunement Servitors: 0

Optifex Directive - Leader & 2 Grunts: 4

New England Team Tournament

Theme: Clockwork Legions
2 / 2 Free Cards     75 / 75 Army

Father Lucant, The Divinity Architect - WJ: +28
-    Corollary - PC: 6 (Battlegroup Points Used: 6)
-    Conservator - PC: 12 (Battlegroup Points Used: 12)
-    Inverter - PC: 15 (Battlegroup Points Used: 10)
-    Diffuser - PC: 6
-    Conservator - PC: 12

Enigma Foundry - PC: 0
Enigma Foundry - PC: 0
Enigma Foundry - PC: 4
Enigma Foundry - PC: 4

Obstructors - Leader & 9 Grunts: 11
Obstructors - Leader & 9 Grunts: 11
Reciprocators - Leader & 4 Grunts: 18
Optifex Directive - Leader & 2 Grunts: 4


Theme: Destruction Initiative
4 / 4 Free Cards     75 / 75 Army

Eminent Configurator Orion - WJ: +28
-    Corollary - PC: 6 (Battlegroup Points Used: 6)
-    Assimilator - PC: 16 (Battlegroup Points Used: 16)
-    Assimilator - PC: 16 (Battlegroup Points Used: 6)
-    Assimilator - PC: 16
-    Assimilator - PC: 16
-    Cipher - PC: 16
-    Diffuser - PC: 6
-    Galvanizer - PC: 5

Attunement Servitors - 3 Attunement Servitors: 0
Elimination Servitors - 3 Elimination Servitors: 0
Elimination Servitors - 3 Elimination Servitors: 0
Elimination Servitors - 3 Elimination Servitors: 0
Algorithmic Dispersion Optifex - PC: 2


Optifex Directive - Leader & 2 Grunts: 4

List Reflections

The Lucant list I played in Champions was given to me by a better known player, and I piloted it rather poorly. I had much better success with my own version of the Lucant list that I played in the Team Tournament, though that very well could be because I'm more familiar with that kind of Lucant CL build rather than the no-heavies version. 

I don't know how much I like the no-heavy version of Lucant in CL, in fact after the weekend I'm more inclined to try and run less infnatry and more heavies.  I doubt this has anything to do with the list itself power wise vs. how I prefer to play. 

I think I want a max of 20 Obstructors and then take either Reciprocators or Eradicators as a center unit, and then fill the list out with more heavies. Reason being that taking a ton of small based units gets hard to cover them sufficiently with Enigma Foundries when you have to spread out due to scenario or the center piece of terrain forcing a split in your forces/Foundries.

I had already learned that I need a Diffuser in my lists which worked great, and a CL list with 3 heavies + Diffuser and a skimpier selection of troops may be enough to push it over the edge. Sadly the troops don't seem to do too much and since they're with Lucant, a canny opponent can use terrain to shield their heavies. When I lost with Lucant it was due to simply missing a way an opponent could land an assassination, or just dropping him into the wrong matchup (Siege 1). 

Conservators in Lucant print money and threat far with the Diffuser and have native pathfinder. At ARM20, they're hard to shoot down under decel and they almost always can be positioned to where they'll get Righteous Vengeance triggered in a CL list.  I'm debating just running 3 Conservators + Diffuser and Corollary in my Battle group and trying to make the list work. There's definitely a lot of room to experiment.

Iron Mother's list is solid and performed well and I simply need some more practice to get a bit better experienced.  It also hurts when you're dice off 6 for an Backlash assassination and so you boost damage, only to roll 17 on the dice and leave the jack with not enough boxes left for the backlash to work.  Also I should probably write "SPAWN YOUR SERVITORS" on my hand before the game starts. There's also the mistake of getting way ahead on attrition and camping 0 focus, forgetting Vlad2 can get rid of the cloud blocking LOS to her and getting her assassinated. 

Orion also has legs and I just need more practice playing him into a shooting opponent rather than a melee one. I think either he or Lucant CL is the best drop into Tharn. I actually dodged Circle all weekend, but I suppose being in the losers bracket most of the time will do that. 

Going Forward

Because I'll be doing a lot of work travel on the other side of the country later this year, this was likely my only con for 2019.  I hope to make it to more local Steam Rollers and to get in at least two Scrum leagues before I start travelling heavily. As much as I want to be competitive, I really feel a calling towards playing Aurora and Syntherion as something fun to play. I honestly hate not having Pathfinder in my infantry lists and I'm wondering if there's not some fun tech with Ciphers with Aurora. From a competitive standpoint I'm thinking about spending more time playing Locke who looks both fun and competitive.

The key take away for me is that I'm staying set on playing Convergence this year. Legion and Trolls are appealing, but I'm enjoying painting the rest of my Convergence army and I just want to stick with them since I feel like there's a lot for me to explore and learn. 

[KKB]Greenhouse Window



Tech Book Face Off: CoffeeScript Vs. Simplifying JavaScript

I really like this setup for a Tech Book Face Off because it's implicitly asking the question of what can be done to improve the quagmire that is the JavaScript language. Should we try to simplify things and pare down what we use in the language to make it more manageable, or should we ditch it and switch to a language with better syntax that transpiles into JavaScript? For the latter option, I picked one of the few books on the CoffeeScript language, aptly named CoffeeScript: Accelerated JavaScript Development by Trevor Burnham. Then, for sticking with JavaScript, I went with a recently published book by Joe Morgan titled Simplifying JavaScript: Writing Modern JavaScript with ES5, ES6, and Beyond. It should be interesting to see what can be done to make JavaScript more palatable.

CoffeeScript front coverVS.Simplifying JavaScript front cover

CoffeeScript


This book was written a few years ago now, in early 2015, but CoffeeScript is still alive and kicking, especially for Ruby on Rails developers as the default front-end language of choice. CoffeeScript is integrated into Rails' asset pipeline, so it gets automatically transpiled to JavaScript and minified as part of the production release process. If you're already comfortable with JavaScript, and even more so if you know Ruby, then CoffeeScript is a breeze to learn.

The ease with which this language can be picked up is exemplified by the book, since it's one of the shortest books I've ever read on a programming language. Over half of the book has more to do with examples, applications, and other stuff tangential to CoffeeScript, rather than the language proper. The book itself is just short of 100 pages while the content on syntax and usage of the language is condensed into the first half of the book.

As all books like this do, the first chapter starts out with how to install the language and configure the environment. It's pretty straightforward stuff. Then, we get into all of the syntax changes that CoffeeScript brings to JavaScript, which essentially defines the language since all of the features are the same as JavaScript's. Chapter 2 shows how function and variable declarations are different, and much shorter. Chapter 3 demonstrates some nice syntactical sugar for arrays in the form of ranges, and iteration can be done more flexibly with for comprehensions. Chapter 4 gets into the syntax features for defining classes and doing inheritance concisely.

Most of the syntax will look quite familiar to Rubyists, including class instance variables denoted with an '@' prefix, the string interpolation notation, unless conditionals, and array ranges. Here's an example from the book showing a number of the syntax features:

class Tribble
constructor: -> # class constructor definition
@isAlive = true # instance variable definition
Tribble.count += 1 # class variable access

breed: -> new Tribble if @isAlive
die: ->
return unless @isAlive
Tribble.count -= 1
@isAlive = false

@count: 0 # class variable (property)
@makeTrouble: -> console.log ('Trouble!' for i in [1..@count]).join(' ')
This code would be about twice as many lines in JavaScript, so the compression is pretty great and the code is much cleaner and easier to understand. Burnham proclaims these virtues of CoffeeScript early on in the book:
Shorter code is easier to read, easier to write, and, perhaps most critically, easier to change. Gigantic heaps of code tend to lumber along, as any significant modifications require a Herculean effort. But bite-sized pieces of code can be revamped in a few swift keystrokes, encouraging a more agile, iterative development style.
Maybe that's stated a bit more strongly than is warranted, but it's still hard to argue with the improved simplicity and cleanliness of CoffeeScript making developers' lives more pleasant.

The last three chapters of the book delve into different frameworks and packages in the JavaScript universe that can be used with CoffeeScript, and the vehicle for exploring these things is a (heavily) stripped  down version of the Trello app. Chapter 5 goes through how to create the front-end portion of the app with jQuery and Backbone.js. Chapter 6 adds a backend server for the app with Node and Express. Chapter 7 explores how to test the app with Intern. All of the code for the front-end, backend, and tests is written in CoffeeScript, and the transpiling is setup to be managed with Grunt. It's nice to see multiple different examples of how to use CoffeeScript anywhere that JavaScript would normally be used, just to get an idea of how to transition to CoffeeScript in multiple ways.

Throughout the book, Burnham presents everything in a straightforward, no-frills manner. Everything is clear and logical, and his concise descriptions are part of the reason the book is so short. He assumes you already know JavaScript—which is much appreciated—and he doesn't go into extended explanations of JavaScripts features. It's just the facts on how CoffeeScript is different and what the syntax is for the features it compresses. It's awfully hard for me not to recommend this book simply because it's so short and to the point. It only took a few hours to read through, and now I know a better way to code JavaScript. There's not much more I can ask of a programming language book.

Simplifying JavaScript


Every language has those more advanced books that assume you already know the language and instead of covering the basics and syntax, it provides advice on how to write idiomatically in the language. I've read these books for C++, Ruby, and JavaScript and found them to be surprisingly enjoyable to read. That was not the case with this book, but before I get too far into criticisms, I should summarize what this book does well.

Simplifying JavaScript is organized into ten chapters with each chapter broken into a set of tips that total 51 tips in all. These tips each explain one new feature of the JavaScript language from the new ES5, ES6, and ES2017 specifications. Some features, like the spread operator take multiple tips to fully cover. Then, the last chapter covers some features of the JavaScript development environment, like npm, that are not part of the language and have been around a bit longer than these newer specifications.

Most of the new features significantly improve and simplify the language, and they include things like:
  • new variable declaration keywords const and let
  • string template literals, which look much like Ruby's string interpolation
  • the spread operator ... for converting arrays to lists and converting lists of parameters to arrays
  • the Map object
  • the Set object
  • new loop iterators such as map(), filter(), and reduce()
  • default parameters
  • object destructuring
  • unnamed arrow functions
  • partially applied functions and currying
  • classes
  • promises and async/await
The arrow functions, spread operator, loop iterators, and destructuring go a long way in making modern JavaScript much more pleasant to program in. All of these features—and likely more in the newest language specs—make CoffeeScript nearly irrelevant, and likely not worth the effort of going through the step of compiling to JavaScript. The language has really matured in the last few years!

Morgan does a nice job introducing and justifying the new features at times:
We spend so much time thinking and teaching complex concepts, but something as simple as variable declaration will affect your life and the lives of other developers in a much more significant way.
This is so true. The code we're reading and writing every day has hundreds of variable declarations and usages, and being able to indicate intent in those declarations makes code much cleaner and more understandable. Getting better at the fundamentals of the language and having these new declarations available so that the most common code is clear and purposeful will more significantly improve code than all of the complicated, esoteric features that only get used once in a blue moon.

These exciting new features and simple explanations were the good parts, so why did I end up not liking this book much? Mostly, it was because of how long-winded the explanations were. Each tip dragged on for what felt like twice as long as it needed to, and the book could have easily been half as long. CoffeeScript showed how to present language features in a clear, concise way. This book took the opposite approach. Then, to make matters worse, it was written in the second person with the author always referring directly to the reader with you this and you that. Normally I don't mind a few references to you, the reader, every now and then, but this was constant so it became constantly aggravating.

Beyond the writing style, some of the justifications for various features didn't hold much water. For example, when trying to rationalize the new variable declarations, Morgan presented an example of code where the variables are declared at the top, and then there are a hundred lines of code before those variables are used again. Then he says, "Ignore the fact that a block of code shouldn't be 100 lines long; you have a large amount of code where lots of changes are occurring." I don't know about you, but I wouldn't declare a variable and then not use it for a hundred lines. I would declare it right before use. He shouldn't have to contrive a bad example like that to justify the new const and let declarations. The improved ability to relate intent in the code should be reason enough.

In another example for why one must be careful when testing for truthy values in a conditional, he shows some code that would fail because a value of 0 is falsey:
const sections = ['shipping'];

function displayShipping(sections) {
if (sections.indexOf('shipping')) {
return true;
} else {
return false;
}
}
Ignoring the fact that I just cringe at code like this that returns a boolean value that should be computed directly instead of selected through an if statement, (don't worry, he corrects that later) there is much more wrong with this code than just the fact that an index of 0 will incorrectly hit the else branch. In fact, that is the only case that hits the else branch. Whenever 'shipping' is missing from sections, indexOf() will return -1, which is truthy! This code is just totally broken, even for an example that's supposed to show a certain kind of bug, which it does almost by accident.

Other explanations were somewhat lacking in clarity. Late in the book, when things start to get complicated with promises, the explanations seem to get much more brief and gloss over how promises actually work mechanically and how the code executes. After having things explained in excruciating detail and in overly simplistic terms, I was surprised at how little explanation was given for promises. A step-by-step walk through of how the code runs when a promise executes would have been quite helpful in understanding that feature better. I figured it out, but through no fault of the book.

Overall, it was a disappointing read, and didn't at all live up to my expectations built up from similar books. The tone of the book was meant more for a beginner while the content was geared toward an intermediate to expert programmer. While learning about the new features of JavaScript was great, and there are plenty of new features to get excited about, there must be a better way to learn about them. At least it was a quick read, and refreshing my memory will be easy by skimming the titles of the tips. I wouldn't recommend Simplifying JavaScript to anyone looking to come up to speed on modern JavaScript. There are better options out there.

Monday, March 23, 2020

Dwarf Leather Daddies

I put the final two highlights on the blue this past week, managed to get the bases and boots based coated, and now I'm working through all the leather belts, straps and satchels on the dwarves.

Warmaster Dwarves Warmaster Dwarf Command Warmaster Dwarf General

I was also curious last night and took one figure to completion. I didn't use a wash on the skin, I'm not sure if that's the way to go yet. You can also see the leather on this guy too, not sure if it needs one more highlight or not. Thoughts?

Warmaster Dwarf Thunderers Warmaster Dwarf Butts

Friday, March 20, 2020

Tech Book Face Off: Facts And Fallacies Of Software Engineering Vs. Programming Pearls 2

Since I've been hitting the tech books pretty hard for a while now, for this Tech Book Face Off I wanted to take a bit of a breather and do a couple of relatively easy reads. These books have been on my to-read list for some time, so I decided to finally check them out. The first one, Facts and Fallacies of Software Engineering by Robert L. Glass is a book in a similar vein as The Pragmatic Programmer in that it relates various tidbits of advice on the craft of software engineering. As for Programming Pearls 2 by Jon Bentley, this book surprised me. I thought it would be somewhat similar to Facts and Fallacies, just more directly related to instructive programming examples than to the software engineering field at large, but it turned out to be quite a bit different, as we'll see in this review.

Facts and Fallacies of Software Engineering front coverVS.Programming Pearls front cover

Facts and Fallacies of Software Engineering

Robert L. Glass is an odd duck. His writing is at the same time strongly opinionated and calmly easygoing. He adamantly argues for each of his observations as 55 facts, with 10 fallacies thrown in at the end, but his discussion of each one is quite conversational. He admits that not everyone will agree with his facts, even though he provides evidence and sources for them. (Well, he does for a majority of them, at least.) I found this book a quick, enjoyable read, and it was worthwhile even if I didn't always agree with his propositions because they always made me think. I'd much rather read a book that I sometimes disagreed with if it challenges me, than a book that's poorly written and says everything I want to hear.

I'm not going to relate every fact and fallacy from the book here, since that would make this review nearly as long as the book, but they do cover the gamut of software engineering. I'll describe them in broad strokes and discuss a few that I found especially interesting.

The first chapter deals with software management related things. The facts are broken up into smaller sections of people (the software engineers), tools and techniques, estimation, reuse, and complexity. A full 22 facts are covered in this chapter, including one about how tools and techniques are over-hyped that I found particularly thought-provoking. Even back when this book was written in 2002, tools were being promoted as a panacea for software development problems while they were simultaneously showing diminishing returns, and Glass was having none of it:
Time was, way back when, that new software engineering ideas were really breakthroughs. High-order programming languages. Automated tools like debuggers. General-purpose operating systems. That was then (the 1950s). This is now. The era of breakthrough techniques, the things that Fred Brooks (1987) referred to as silver bullets, is long since over. Oh, we may have fourth-generation languages ("programming without programmers") and CASE tools ("the automation of programming) and object orientation ("the best way to build software") and Extreme Programming ("the future of the field") and whatever the breakthrough du jour is. But, in spite of the blather surrounding their announcement and advocacy, those things are simply not that dramatically helpful in our ability to build software.
What's most interesting is that 17 years later, the hype machine hasn't stopped, and it shows no signs of slowing down. I wouldn't say that's surprising, given that software engineering is such a massive sector, and people continue to try to make money off of it however they can, but it shows how relevant this book still is. Advances in software engineering ideas do still happen, but they are still incremental. It isn't that incremental is bad, but it is all that we should expect now. Productivity free lunches aren't likely to come about anymore until the next breakthrough technology happens, and that may not be software but something else entirely.

Chapter 2 is about the software life cycle with sections on requirements, design, coding, error removal, testing, reviews and inspections, and maintenance. Maintenance in particular is a fascinating subject in software because it ends up taking the majority of the time and cost of any given project, mostly without our realizing it. It's also quite difficult and no one wants to do it because the documentation sucks. There's a reason for that:
To solve those problems, software people have invented the notion of maintenance documentation—documentation that describes how a program works and why it works that way. Often such documentation starts with the original software design document and builds on that. But here we run into another software phenomenon. Although everyone accepts the need for maintenance documentation, its creation is usually the first piece of baggage thrown overboard when a software project gets in cost or schedule trouble. As a result, the number of software systems with adequate maintenance documentation is nearly nil.
Here we can see both Glass' conversational writing style and the reasonable way of thinking that he shows in most of his facts and fallacies. It's hard to argue with this one, especially because I think most of us have been in similar situations.

The next chapter is about software quality, including sections on quality, reliability, and efficiency. Like the other chapters, these facts are mostly obvious to anyone who has been working in the field for more than a few years, but it's always good to refresh your memory on these ideas. The last chapter of facts is just a single fact on research: many researchers advocate rather than investigate. I can't say whether or not this is true from my own experience or reading, but I'm not too concerned about it.

Starting with chapter 5, the next three chapters deal with the 10 fallacies. Chapter 5 loops back around to management with similar sections to the first chapter. The fallacies include things like, "you can manage quality into a software product," and "software needs more methodologies" that are hard to argue with. You can't, and it doesn't. The next chapter mirrors chapter 2 with some fallacies on the software life cycle. I thought he was unfair in his discussion of the fallacy, "given enough eyeballs, all bugs are shallow" by saying:
This is probably just wordplay. But it is patently obvious that some bugs are more shallow than others and that that depth does not change, no matter how many people are seeking them. The only reason for mentioning this particular reason here is that too many people treat all bugs as if their consequences were all alike, and we have already seen earlier in this book that the severity of a bug is extremely important to what we should be doing about it. Pretending that turning scads of debuggers loose will somehow reduce the impact of our bugs is misleading at best.
This seems like a deliberate misinterpretation of the idea of the quote. It's not saying that more eyeballs will make bugs less critical. It's saying that any given bug is easier to find if more people are looking for it because the more people that look for the bug, the more likely that a person with the right expertise will see it and be able to fix it quickly. Or it will be more likely that someone looking for the bug will randomly happen to look in the right place and spot its signature quickly. However, I think there are still issues with depending on this approach for open source software development, but for other reasons. Most open source projects don't have the luxury of having hundreds or thousands of programmers working on it. Frankly, most projects are lucky to have more than one programmer working on it, so the responsibility of finding and fixing bugs still falls on the programmer writing the code. Even if the project has high visibility, pull requests need to be of high quality, or more bugs will be introduced over time than will be fixed and the whole project will degrade.

I also took issue with the fallacy in the last chapter: "you teach people how to program by showing them how to write programs." Don't get me wrong, I do think this statement is false, but for different reasons than Glass gave. He thinks it's more important to teach budding programmers how to read code and that academia isn't doing that:
I know of no academic institution, or even any textbook, that takes a reading-before-writing approach. In fact, the standard curricula for the various computing fields—computer science, software engineering, information systems—all include courses in writing programs and none in reading them. 
I disagree on three counts. First, let's get the easy one out of the way. Programming is about more than writing or reading code. Teaching programming involves teaching critical thinking skills, problem solving, systems thinking, user psychology, and so much more! Second, and more directly related to his reasoning, the exact same approach is used in mathematics. Schools teach students how to write math solutions well before teaching them how to read math solutions. Most people will never get to the point of reading and understanding mathematical proofs, but everyone starts with solving basic arithmetic problems. That's how we start in programming, too—by writing basic programs.

Third, I would argue that universities and textbooks are, in fact, teaching students to read programs at the same time as writing them. The examples in the books are all there to read, and the student must read and understand them in order to write their own functioning programs. The first example programs may be short and simple, but I would hardly expect someone brand-new to programming to read hundreds of lines of code without first being taught the syntax. Learning to read is unique in that the student is being taught a skill that is required in order to learn most other skills, so of course we learn to read before we learn to write, but not much earlier. We start learning both in kindergarten, right? Besides, most people don't know how to read effectively anyway, even though they technically learn to read first, so I don't see why a pure reading-before-writing approach to programming would necessarily be better than what is currently being done.

As you can see, some topics in this book are quite controversial, and that's why I really enjoyed it. No one who reads this book will agree with everything, and that's okay. It's meant to raise a debate, and Glass does a great job of presenting a strong case that you can take a stance against if you disagree. It got me thinking over ideas that I've held on to for a long time, and we all need that from time to time. It's also a fairly short book, so there should be no excuse to not read through it. I highly recommend it.

Programming Pearls 2

In the introduction I said this book surprised me, and what I meant by that was that it was not at all the book that I expected. From the title alone, I was expecting a book similar to Facts and Fallacies of Software Engineering in that it would relate a number of experiences and advice from Jon Bentley's career about how to do software development more effectively. I suppose that's what this book is, in a way, but it's more of a combination of an informal algorithms book and a practice set of programming problems.

It's not nearly as thorough or rigorous as Introduction to Algorithms (CLRS) or Algorithms by Sedgewick, but it gives a passable review of most of the fundamental algorithms for sorting, searching, and storing data. The first chapter starts off with an interesting little algorithm that I had never seen before on sorting a list of numbers with a restricted range using an array of bits. In this case it was telephone numbers, and it was accompanied by a story about how he was helping a new colleague with a problem, but the algorithm itself could be useful in plenty of situations. 

The next chapter continued the thread from the first chapter with a few more problems that could be neatly solved with novel algorithms, like finding all possible anagrams or swapping unequal halves of an array. The third chapter covered ways to make programs much more efficient by correctly structuring the data that was being manipulated. The classic example is using an array instead of a set of numbered variables, but Bentley gave other examples as well, like creating a simple template language for form letters. 

Chapter 4 was all about program correctness, using the binary search algorithm as a conduit for discussing the pitfalls of complexity and how to formally verify a program (or at least a function, since formal verification just doesn't scale). The last chapter in this first part of the book quickly covers testing, debugging, and performance timing. That completed the preliminaries, which is what the first part of the book was about, and throughout these chapters Bentley had short, direct advice about how good programming was about balance:
Good programmers are a little bit lazy: they sit back and wait for an insight rather than rushing forward with their first idea. That must, of course, be balanced with the initiative to code at the proper time. The real skill, though, is knowing the proper time. That judgment comes only with the experience of solving problems and reflecting on their solutions.
I think some later writers in the field took this idea of the lazy programmer to the extreme, but I like this nicely moderated perspective more. He had a similarly measured view about performance optimizations:
Some programmers pay too much attention to efficiency; by worrying too soon about little "optimizations" they create ruthlessly clever programs that are insidiously difficult to maintain. Others pay too little attention; they end up with beautifully structured programs that are utterly inefficient and therefore useless. Good programmers keep efficiency in context.
There are no universal answers in programming, so there shouldn't be any universal advice, either. These comments make the point that you can't turn off your brain when programming. You have to constantly consider everything that would have an effect on the problem at hand in order to come to a more optimal solution.

The second part of the book is all about performance. Chapter 6 kicked things off with a look at the n-body problem in physics for simulating the forces that bodies exert on one another. Making the simulation fast was not only about developing a good algorithm, but also using the right data structure, tuning the code for the machine it was running on, and optimizing performance critical loops in assembly. A recurring theme in the book was that there's no silver bullet, and this case study exemplified that with its multifaceted optimization process.

The rest of the chapters in this section expanded on the ideas brought up in chapter 6. Chapter 7 talks about how to estimate with back of the envelope calculations. Chapter 8 discusses various algorithm design techniques including the all important divide-and-conquer approach. Chapter 9 delves into when and how you should do code tuning to get the biggest benefit. Chapter 10 looks at how performance can be improved by reducing space, both of the program code and the data that it operates on. Every chapter had succinct little examples and highly condensed code to show the essence of optimized programs, along with interludes of advice like this:
[E]very now and then, thinking hard about compact programs can be profitable. Sometimes the thought gives new insight that makes the program simpler. Reducing space often has desirable side-effects on run time: smaller programs are faster to load and fit more easily into a cache, and less data to manipulate usually means less time to manipulate it. The time required to transmit data across a network is usually directly proportional to the size of the data. Even with cheap memories, space can be critical. Tiny machines (such as those found in toys and household appliances) still have tiny memories.
It's good to remember that not all programming is done on massively powerful processors, even today with a supercomputer on every desk and in every pocket. We have just as many small processors with limited memory and a tight power budget doing plenty of complex calculation tasks.

That brings us to the last section of the book on five interesting programming problems. The first one is on sorting with quicksort. The second one is about how to draw a random sample from a larger collection. The last three are on searching, heaps, and strings. The last problem dealing with strings was a great way to end because it was actually about how to teach the program how to generate english words and sentences using example material. It was a chapter on machine learning written before it was cool.

On the whole, this book was a fairly enjoyable, quick read. Bentley is clear and to the point, even to the point of being abrupt. As an algorithms book, it's not up to the level of the more formal algorithms books, and it wouldn't be very useful as a first book on that material. It is a good summary of the basic sorting and searching algorithms with some interesting unique algorithms thrown in to spice things up, making it a decent review for the more experienced programmer. If you're looking for an easy second or third book on algorithms to peruse, it's worth picking up.


So it turned out that these two books are not directly comparable, but hey, it happens. They were both enjoyable reads. I would say Facts and Fallacies of Software Engineering was somewhat more enjoyable than Programming Pearls 2 with Glass' way of challenging your assumptions and long-held beliefs, but both books are worth a look in their own right. Programming Pearls 2 does a good job of reviewing the field of algorithms with a few novel ideas thrown in the mix. It all depends on what your interested in at the moment: high-level software engineering issues or algorithmic programming problems.

Thursday, March 19, 2020

Rank Has Its Priveledges

More work has been done on the Greys than it looks and I've now finished rereading O'Brien's Post Captain for the first time in, well, years, possibly decades.  Hopefully, I'll be done with the Greys on Friday and can get back to French skirmishers. I'm very happy though that I'm sticking with my now usual new toy soldier crossed with old school wargaming look. (Not the Gilder old school style obviously)

At least the British now have a General!

Darksiders III: Deluxe Edition Free Download

Darksiders III - is a hack and slash action-adventure video game developed by American studio Gunfire Games and published by THQ Nordic. It is a sequel to Darksiders II and the third entry in the Darksiders series.


Return to an apocalyptic Earth in Darksiders III, a hack-n-slash Action Adventure where players assume the role of FURY in her quest to hunt down and dispose of the Seven Deadly Sins. The most unpredictable and enigmatic of the Four Horsemen, FURY must succeed where many have failed – to bring balance to the forces that now ravage Earth. Darksiders III is the long-anticipated, third chapter in the critically-acclaimed Darksiders franchise. Fury, who must rely on her whip to restore the balance between good and evil on Earth.
1. FEATURES OF THE GAME

Play as Fury, a mage who must rely on her whip & magic to restore the balance, between Good and evil on Earth.
Harness Fury's magic to unleash her various forms, each granting her access to new weapons, moves plus more.
Explore an open-ended, living, Free-form game world in which Fury Moves back and forth between environments.
Defeat the new Seven Deadly Sins and their Servants who range from mystical Creatures to degenerated beings.
Expansive Post-Apocalyptic environments that take the Player from the Heights of heaven & to the Depths of Hell.

Game is updated to latest version

Included Content

▪ Darksiders III: Deluxe Edition - Pre-order DLC (special option armor)

2. GAMEPLAY AND SCREENSHOTS
3. DOWNLOAD GAME:

♢ Click or choose only one button below to download this game.
♢ View detailed instructions for downloading and installing the game here.
♢ Use 7-Zip to extract RAR, ZIP and ISO files. Install PowerISO to mount ISO files.

DARKSIDERS III: DELUXE EDITION DOWNLOAD LINKS
http://pasted.co/af29b5ae      
PASSWORD FOR THE GAME
Unlock with password: pcgamesrealm

4. INSTRUCTIONS FOR THIS GAME
➤ Download the game by clicking on the button link provided above.
➤ Download the game on the host site and turn off your Antivirus or Windows Defender to avoid errors.
➤ When the download process is finished, locate or go to that file.
➤ Open and extract the file by using 7-Zip, and run 'setup.exe' as admin then install the game on your PC.
➤ Once the installation is complete, run the game's exe as admin and you can now play the game.
➤ Congratulations! You can now play this game for free on your PC.
➤ Note: If you like this video game, please buy it and support the developers of this game.
Turn off or temporarily disable your Antivirus or Windows Defender to avoid false positive detections.






5. SYSTEM REQUIREMENTS:
(Your PC must at least have the equivalent or higher specs in order to run this game.)
Operating System: Windows 7, Windows 8, Windows 8.1, Windows 10 | requires 64-bit
Processor: AMD FX-8320 (3,5 GHz) / Intel i5-4690K (3,5 GHz) or better processor
Memory: at least 8GB System RAM
Hard Disk Space: 25GB free HDD Space
Video Card: GeForce GTX 660 / Radeon R7 370 with 2 GB VRAM or better graphics
Supported Language: English, French, Italian, German, Spanish, Polish, Russian, Portuguese-Brazil, Arabic, Korean, Simplified Chinese, and Japanese language are available and supported for this video game.
If you have any questions or encountered broken links, please do not hesitate to comment below. :D

Why Self-Compassion?

I've read so many self-help books, and upon reviewing the most helpful ones, I keep saying, "that's another way of saying to have self-compassion". The concept that ties all the ideas in these self-help books boils down to self-compassion.

I also recommend The 7 Habits of Highly Effective People for a roadmap on how to organize your life in a practical manner, as a very effective and powerful way of doing your to-do lists, and so forth. I summarized the book here in two parts, this is the first part.

But it's really self-compassion that can motivate you to be effective in the first place, and to really stick to your goals! I wasn't able to follow any sort of positive habits for long when I read The 7 Habits in college, because of being easily demoralized.

Therefore, in this post, we'll explain why self-compassion is such a powerful concept. Practicing self-compassion is personal and isn't applied in a "cookie-cutter" way. In fact, having self-compassion is extremely challenging and difficult, as you have to find out what works for you.

In this past post, I superficially touched upon a self-compassion exercise, so in this post, we'll explain why self-compassion is key, by summarizing Self-Compassion: The Proven Power of Being Kind to Yourself  by Kristen Neff, Ph.D., who is the foremost authority on the subject.

In the horrible Harry Harlow experiments, he nevertheless proved that love and connection are more basic than food and water. The poor baby monkeys were taken away from their mothers, and had to choose between the fake cloth mom with no food/water, and the fake wire mom with food/water.

Harlow himself thought that the babies would stick with the wire mom the whole time because of the food and water, but found out the exact opposite. The babies clung to the cloth mom and when hungry, run toward the food/water, and then immediately run back to the cloth mom.

What this experiment proved is that the basic need of all humans is love and connection, more so than even food and water. When you don't have love and connection with others, it can lead to depression, anxiety and even suicide.

This sense of belonging is primary and deep, even in the most "macho" rituals, American football. By being a diehard fan of one team, you embrace other fellow fans. You see strangers hugging each other, sharing food and beer in these "tail-gate" parties. There's a huge sense of connection if you ever participated in one of these parties.

Having self-compassion sounds soft and fluffy, but in reality, it can be very tough and painful at times, as we will see down the road.

PROBLEM ONE: Comparing ourselves to others leads to disconnection and suffering

At least in the Western world, we live in an extremely competitive society where we must excel, and it's not "good enough" to be average, you have to be above average.

This is so illogical, because we can't be above average in all things, and there are always going to be people who are more beautiful, smarter, more successful than us.

Sadly, by comparing ourselves to others and being competitive in wanting to be above-average, people tend to look down upon others to feel better about themselves.

We may get a rush from having higher self-esteem when we mistakenly feel that we are more "successful" than another person.

However, if we meet someone who is more "successful" than us, then our self-esteem plummets, and we feel like crap.

Therefore, comparing ourselves to others leads to this emotional see-saw. If we find we're better, we get elated, if we don't measure up, we get depressed.  Even worse, when we protect our self-image to avoid feeling bad about ourselves, we don't acknowledge our faults, rather blaming the other person, even though "it takes two to tango".

This leads to ongoing conflicts, which causes disconnection from your loved ones. Further, by not seeing our flaws, that leads to stagnation and lack of growth, because how can you improve if you don't acknowledge your faults?

The solution to prevent these comparisons is self-compassion. Stop judging and evaluating ourselves altogether! Don't label ourselves as "good" or "bad" but rather accept ourselves openly, and treat ourselves with kindness like a best friend.

Does this work? Yes! By having self-compassion you accept yourself because you're like everybody else! Everyone has flaws, we're no different. By accepting ourselves for who we are, then we can accept others as well, and there's no reason to compare.

When you love and truly accept yourself, you're not going to look down on those who are less fortunate. Likewise, you're not going to have that sinking feeling that you're not doing enough when you see others drive fancy cars.

Caveat: There are many people who are rather harsh with themselves, but would never be that way with others. However, by being nasty to yourself, you're not going to feel good about yourself.

Why not pursue Win/Win where you're compassionate towards yourself and others?

I notice that I tend to feel sour when someone I dislike becomes more successful (comparing), and I get down on myself for not being that successful. Then I feel bad that I can't forgive the person and let go. It's an absolutely awful feeling, it doesn't do me any good, and certainly not to the more successful person. I really hate that pinched soul feeling.

Next, I continue to feel bad about myself for not being charitable, and this spirals downward to being angry with myself, "why can't I just forgive!".

However, when I have self-compassion and realize that forgiveness is something I struggle greatly with, and indeed a lot of people have the same issues, I can be more patient with myself and move toward being less judgmental.

Allowing yourself to be kind to yourself humanizes you (as you suffer just like everyone), as well as humanizing others because you understand deep down that they're going through same and/or different struggles as well.

In other words, as part of humanity, you are a worthy person, just like everyone else. When you see yourself as different than others, that again leads to feeling disconnected and not belonging to humanity.

Indeed, dehumanizing others leads to disconnection, which has led to unspeakable crimes against humanity. By seeing "non-Aryan" groups as other and less than human, it was easy for an entire nation to exterminate and torture people "because they're not like us".

PROBLEM 2: Feeling lonely and isolated

We looked at the first part of self-compassion which is self-kindness: gentle understanding of ourselves, rather than being critical and judgmental.

The second part of compassion we briefly touched upon. Why should we be kind to ourselves? Because we're all part of humanity. As we're kind to others, then it makes logical sense to be kind to ourselves.

The concept here is "we're all in this together". We recognize this common human experience of suffering, acknowledging the interconnected nature of our lives (Harry Harlow experiment), indeed life itself.

Therefore, compassion is relational. By seeing people as part of humanity, rather than "other" as the Nazis did, we feel connected.

As explained above, our deepest need is to belong, but when you compare yourself to others, this disconnect leads to loneliness. The KKK feel superior to others because they're white, and the "other" is not. The same can be said of Men, Women, Democrats, Republicans, Americans, Russians, Christians, Muslims, and the list goes on. We're part of this group, therefore, we're superior to this other group. Fanatical group identity is dangerous as it leads to disconnection and even genocide. 

However, if you refuse to hold this view and have compassion toward yourself and others, regardless of group affiliation, you have connection. Instead of seeing differences, you reframe and see how we're so similar to one another. We all want love and connection; that's our similarity.

So when our sense of self-worth and belonging is grounded in simply being human, we can't be rejected or cast out by others. It makes no sense to say that you're rejected by humanity, because you're human.

Remember your shared humanity. That can help you to have compassion for who you are. It helps to have others be kind toward you, but they can't be there with you 24/7. However, you can be with yourself 24/7, so you might as well be kind to yourself using the "best friend" approach discussed in this post.

PROBLEM 3: Suffering

This is the hard part of self-compassion. Self-kindness and common humanity we discussed above. The third and last step is mindfulness.

You must be aware of your suffering, but in a balanced way, where you neither diminish, or make it out to be worse than it is. I tend to make a mountain out of an ant-hill.

Therefore, in this third part of self-compassion, you need to be mindful - clear seeing and nonjudgmental acceptance of what's occurring in the present moment.

You're facing up to reality, neither underestimating or over-exaggerating things. First step is to recognize when you're suffering instead of suppressing it, because you can't heal what you can't feel. Be aware of your pain. By stuffing and ignoring pain, it can explode.

A good analogy of awareness is thus: Awareness is the blue sky. Your feelings and thoughts are the birds flapping around. Identify with the sky, instead of the birds. If you remain in awareness (i.e. sky) and not react to the thoughts and feelings (birds), you can be calm and centered as the sky doesn't shift and change in a feckless manner.

You can't change your thoughts and feelings very well, but you can change your reactions to them. There are many meditation techniques, but the key here is to hold and be aware of the pain, and don't numb it.

Indeed, people who suffer from PTSD tend to numb their emotions, as a very understandable mechanism to avoid feeling the immense pain of trauma.

But by having this numbing of emotions, they can't feel the positive emotions of joy, creativity, love. When you numb, you numb all emotions. Often, people who suffer from PTSD say that they're living zombies and they don't know how to have fun anymore.

The hard work in PTSD involves working through the painful memories in a safe, secure environment. The acknowledgment, and being one with the pain, is the really difficult part of self-compassion.

One example that makes us all feel bad about ourselves is when we hear a baby crying which irritates us, but we judge ourselves for having these thoughts, "what a horrible person I am for having that thought, it's only a baby, a nicer person would feel sympathy rather than being triggered".

However, if you have self-compassion, you stop the judgment. You become aware (sky) of the irritation (birds) you're having, you acknowledge the negative thought, while recognizing that surely a lot of people would feel the same way, and the thought will eventually pass!

A silly example is when I went to a party. I tend to need at least 5 large glasses of wine and/or beer to feel socially comfortable. The extremely uncomfortable feeling of being socially awkward has been too hard for me to deal with.

However, at a recent party, I decided not to drink - this wasn't too daring, because there were only 3 people at the party that I don't know that well. I decided to practice self-compassion, since I just completed reading the book.I decided to be one with being socially awkward.

What helped me was chanting exactly how I felt, "socially awkward, socially awkward, socially awkward". However, after 1 hour (I'm "slow to warm up"), I stopped feeling awkward, and I ended up enjoying being in the moment and having meaningful connections.

I'm not sure if this strategy would work if I'm in a party with people I barely know, but this is a small step to being aware.

Dr. Neff recommends that when you feel suffering, to have a mantra, in your words, along this line:

This is a moment of suffering
Suffering is part of life
May I be kind to myself in this moment
May I give myself the compassion I need

I kind of like Brene Brown, Ph.D. (author of Daring Greatly) mantra where one of her interviewees, when in pain would simply say, "pain, pain pain". Or you can say "ouch, ouch, ouch", to acknowledge the pain, as well as the rest of the mantra as suffering being part of humanity, and to give yourself kindness and compassion. It's best if it's in your own words.

On a positive note, when you have awareness, you're going to have awareness of positive emotions too! In this situation, you can hold it in loving awareness and really make that feeling bloom! You can experience love and joy with more awareness and rejoice in it - it actually overflowed to my coworkers and strangers!

Using the three part component of self-compassion as a way toward love and connection, it helps you to deal with pain and suffering.

I then chuckled at Dr. Neff's stages of self-compassion, because I went through the same thing. Initially, as I had self-compassion, I had this outpouring of love toward my coworkers, and work was light - I actually made some rather creative suggestions which surprised even me. I was enamored with self-compassion.

However, I then saw the hard work of self-compassion. It doesn't take the pain away at all, rather it helps you to be more resilient and deal with pain in a more effective way.

Instead of numbing or burying your feelings, which will pop up again, as survivors of trauma would all attest, in the form of disturbing intrusions, horrific nightmares and flashbacks, rather self-compassion holds you in awareness.

With self-compassion, you gain the resilience to work on painful emotions, feelings and thoughts head on. While having compassion for yourself that you're suffering like the rest of the world, and being aware of the pain, you can wait for the pain to pass. You can weather these negative emotions. This leads to emotional resilience, and with practice, you become better and better at it.

PROBLEM 4: Being successful

If you think about it, if you see someone more successful than you, and he brags to you about all the things he bought, where you "only" have a run of the mill sedan, it'll be hard to be friends with him.

Therefore, what if you're highly successful, does this mean you'll be disconnected from others? If you have self-compassion, no! As part of humanity (principle 2 of self-compassion), you'll have shared joy.

You are concerned for your own well-being as well as others, so you want both to succeed! By recognizing our inherent connectedness, Dr. Neff writes, "When we're part of a larger whole, we can feel glad that 'one of us' has something to celebrate".

You celebrate with exuberance in the success of others with self-compassion. In fact, with self-compassion, you can genuinely feel that way, instead of grudgingly when you see your friends being more successful than you.

Instead, armed with self-compassion, you become aware of other people's positive traits and fully appreciate them, not taking them for granted. You rejoice in yourself, just as you rejoice in others.

PROBLEM 5: I'm not going to be successful if I have self-compassion

The opposite is true. So many psychological studies have shown that intrinsic motivation is more powerful than extrinsic motivation.

If you're stuck in the self-esteem, need to prove myself trap, you're doing things to be successful, to look smart, athletic so that you can be admired, which strokes your ego. This is extrinsic motivation.

Let's say the activity is very grueling, streaming as a career. With extrinsic motivation, your self-esteem increases when your viewer numbers go up, and then it crashes when your number goes down.

I know this very well. In the early stages of streaming, I actually got depressed when my viewer number went from 10 to 9, WTF!

But you still stream for those numbers because when you grow, your self-esteem does as well, and I did get emotional high's when I got an average of 20 in one month - it's like a drug!

However, during summer, when many are off on vacation, your numbers tend to be lower for the next 3 months. Since you're streaming for self-esteem and those numbers, you may be demoralized and then give up.

Further, by wanting to be successful so you can prove yourself as the "better" streamer (stroking your ego), you're afraid to take creative risks, make mistakes, for fear of losing viewers. You then look "wooden" which is the death-knell in entertainment. You keep to a regular script which can get stale, also another way to make yourself bored and not wanting to stream anymore.

However, if you have self-compassion, which leads to awareness of what you truly want in life, you decide to stream because you love the process as well as your viewers.

You enjoy the connection and the challenge of negotiating chat and gameplay, and finding new creative angles to be entertaining.

This is intrinsic motivation, you're doing something because you want to do it. You don't care if you fail and your numbers drop like flies, because your self-esteem isn't harmed in any way, because you have self-compassion.

If you do something "dumb" while streaming, you'll be able to do your "ouch" mantra, hold the embarrassment, and move on, with emotional resilience. You can take enormous risks (historically leading to major advancements in technology and innovation) because you simply don't care about social rejection or judgment, or low viewer numbers. You are authentic and free.

If you're stuck on an issue with streaming, you're not afraid to ask for help for "fear of looking stupid". In other words, you're not controlled by societal pressures when you have self-compassion.

You do your own thing with utmost courage, authenticity, honesty and integrity, screw the rules! Contrary to what people think, self-compassion isn't "wimpy", but bad-ass! What's more bad-ass than being true to yourself and a "rebel".

At any rate, it appears that those who do something they absolutely love tend to be more successful than someone who's doing it to prove themselves.

When you love something, you never get tired of doing it, to the point where you may have to work on self-care issues such as eating regular meals and getting enough sleep (I'm thinking specifically video gaming).

When you're doing something to prove things, you're going to be demoralized when there's a glitch, a temporary obstacle, and failure, and you may quit altogether.

The person who's spending and practicing that many hours because of the enjoyment will tend to be better at the activity than someone who quits in fits and starts due to obstacles in the way.

I wanted to outline the three components of self-compassion here, and present the major arguments for self-compassion.


There are many exercises in the book that I won't outline here, so if you feel that the concept of self-compassion makes sense and can make a difference in your life, I highly recommend Self-Compassion: The Proven Power of Being Kind to Yourself

I found the concept of self-compassion jump started me on being way more pro-active in self-care and fulfilling my specific goals. Perhaps borrow the book from the library or look through the book at the bookstore. Do the exercises that resonate with you. Above all have self-compassion!

Note: I have been including the How of Happiness link in the bottom of all my posts, but I found Dr. Neff's Self-Compassion equally important, so I'll be alternating posts with these books.