Blog

PyEnv to Manage Multiple Python Versions (MacOS)

If, after following the installation directions for PyEnv at https://github.com/pyenv/pyenv#homebrew-on-macos, you run into an issue setting your python version for ‘global’, ‘local’, or ‘shell’ and you are using ZSH as you shell rather than BASH, there is a good possibility you either:

  1. Made the obvious mistake of not switching out which shell you are using from BASH to ZSH in all of your installation commands as noted in the instructions (common mistake)

or (what I ran into)

  1. The installation commands found in the installation guide failed to place the necessary shell scripts in the proper file for ZSH for your particular setup. I found that moving the shell scripts from my ~/.zshenv file to the bottom of my ~/.zshrc file solves this problem and I can once again properly set the python version I want to use using ‘pyenv global 3.8.1’. Now when I check the version ‘python –version’ in my terminal (I use iterm), I get 3.8.1 as expected.

Securing Express APIs: Using the DotEnv library to keep secrets safe (What-Why-Where-How)

This video is a live coding tutorial held during one of my full-stack web development courses. It is part of a full series on Securing Express API applications. In this video we run through the process of setting up a .env file to be read by the DotEnv NPM package, adding a .gitignore file to the project so that the .env will not be added to git repositories, and adding a config module responsible for reading the environment variables. The concepts surrounding each of the steps above are covered in great detail in order to make sure that my students understand the why behind the process rather than just doing.

Please keep in mind that this is a live coding session and therefore the quality is not necessarily of production value.

JavaScript: Design Patterns 08 – Abstract Factory Pattern

Abstract Factory Pattern

This is an enhancement of the Factory Pattern, in that it operates in basically
the same way, the factory creates objects based on the passed in arguments.
The difference lies in that additional abstraction is added to the factory.

The added abstraction

The purpose of the traditional factory pattern is to remove, from the codebase,
the redundant object creation code by encapsulating it within a reusable object
the factory.

The abstract factory pattern takes this a step further by removing from the
factory its knowledge of the objects it is creating, making the factory extremely
generic. Due to this level of abstraction, it becomes important that the objects
the factory will be building are first registered with the factory prior to the
factory being used. The registration of objects can be done:

  • Internally to the factory in the init function
  • Dynamically through factory configuration passed to the factory by the caller
  • Through a registration function on the factory to which constructor functions are
    passed by the caller

How the registration occurs is totally up to the needs of the system.

Script: Supplemental for Example Below
// Constructor functions that will be used inside of the Lizard Factory
function Lizard(args) {
this.kind = args.kind;
this.moves = args.moves;
}
Lizard.prototype.bites = function() {
console.log(`${this.kind} just bit me really hard as it ${this.moves} away.`);
};
Lizard.prototype.says = function() {
console.log(`I am a ${this.kind}.`);
};

function Chameleon(args) {
Lizard.call(this, { kind: 'Chameleon', moves: args.moves });
this.name = args.name;
this.color = 'green'
}
Chameleon.prototype = Object.create(Lizard.prototype);
Chameleon.prototype.changeColor = function(color){
this.color = color;
console.log(`${this.kind} just changed color to ${this.color}, you no see me!`);
}

function Dragon(args) {
Lizard.call(this, { kind: 'Dragon', moves: args.moves });
this.name = args.name;
}
Dragon.prototype = Object.create(Lizard.prototype);
Dragon.prototype.fireBreath = function(){
console.log(`${this.kind} breath, you are now on fire.`);
}
Script: Abstract Factory Example
// Abstract and more generic animal factory
let AnimalFactory = function(){
// Object to hold registered types with associated constructor functions
this.types = {};

// object creation function becomes more generic
this.create = function(type, args){
return new this.types[type](args);
};

// type + constructor registration method
this.register = function(type, builder){
this.types[type] = builder;
};
}

// in this example, we register the types that can be created by the factory
// externally using the register method of the factory
let factory = new AnimalFactory();
factory.register('lizard', Lizard);
factory.register('chameleon', Chameleon);
factory.register('dragon', Dragon);

let baseLizard = factory.create('lizard', { kind: 'lizard', moves: 'speedy little demon' });
console.log(baseLizard);

let myChameleon = factory.create('chameleon', { name: 'Freddy', moves: 'very very slow' });
console.log(myChameleon);
myChameleon.changeColor('red');
let myDragon = factory.create('dragon', { name: 'Freddy', moves: 'very very slow' });
console.log(myDragon);
myDragon.fireBreath();

JavaScript: Design Patterns 07 – Factory Pattern

Factory Pattern

Short Def: Used to encapsulate the creation logic for a related family of
objects.

Long Def: Used commonly to simplify object creation in systems where numerous similar objects are
dynamically created based on a few differing properties. The pattern takes redundant
object creation code that might be scattered throughout a system and wraps that
code in a single object in a reusable form that can be used across the system.

Another key attribute of this pattern is that the factory encapsulates the logic
needed to create objects of different types based on the arguments provided. This
removes the need for the caller to be concerned with specifying the object type
needed and it therefore relies on the factory to provide what it needs.

Script: Supplemental for Example Below
// Constructor functions that will be used inside of the Lizard Factory
function Lizard(kind, moves) {
this.kind = kind;
this.moves = moves;
}

Lizard.prototype.bites = function() {
console.log(`${this.kind} just bit me really hard as it ${this.moves} away.`);
};

Lizard.prototype.says = function() {
console.log(`I am a ${this.kind}.`);
};

function Chameleon(name, moves) {
Lizard.call(this, 'Chameleon', moves);
this.name = name;
this.color = 'green'
}

Chameleon.prototype = Object.create(Lizard.prototype);

Chameleon.prototype.changeColor = function(color){
this.color = color;
console.log(`${this.kind} just changed color to ${this.color}, you no see me!`);
};

function Dragon(name, moves) {
Lizard.call(this, 'Dragon', moves);
this.name = name;
}

Dragon.prototype = Object.create(Lizard.prototype);

Dragon.prototype.fireBreath = function(){
console.log(`${this.kind} breath, you are now on fire.`);
};

Script: Factory Example
// Lizard Factory: setup to select the appropriate object type to create
// based on a keyword passed in followed by an arguments array that is
// passed to the appropriate object constructor function.
let LizardFactory = function(){
this.create = function(type, args){
switch(type){
case 'chameleon':
return new Chameleon(...args);
case 'dragon':
return new Dragon(...args);
default:
return new Lizard(...args);
break;
}
};
};

let factory = new LizardFactory();

let baseLizard = factory.create(null, ['base lizard', 'speedy little demon']);
console.log(baseLizard);

let myChameleon = factory.create('chameleon', ['Freddy', 'very very slow']);
myChameleon.changeColor('red');
console.log(myChameleon);

let myDragon = factory.create('dragon', ['Freddy', 'very very slow']);
myDragon.fireBreath();
console.log(myDragon);

JavaScript: Design Patterns 06 – Singleton Pattern

Singleton Pattern

Used when only a single instance of an object should exists and that instance
should be the one used no matter who or what is calling or using
the state or abilities of that object type. Used mostly when a system requires
an orchestrating object to hold state or have abilities that must be shared
across the entire system.

Benefits
– Delayed instantiation: the singleton object is not created until the first calling
to the object is received and a reference to that object is then held for the life
of the system’s execution.
– Exists across the entire system: the singleton when subsequently called
for use, will provide the caller a reference to the exact object instance that was
created upon first call.
– Consistent interface for accessing the singleton object: there is a function or object
that handles the creation of and holds the reference to the single object instance.

let dataContextSingleton = (function(){
// Holds the reference to the singleton object instance
var singletonInstance;

// Private function used to build the singleton object instance if it
// does not yet exist
function init(){

// Private state/functions for singleton object
let _objectCollection = [];

// Public state/functions
function add(obj){
_objectCollection.push(obj);
}

function find(id){
let found = [];
for(let obj of _objectCollection){
if(obj.id === id) found.push(obj);
}
return found;
}

// Using module reveal pattern to expose API
return {
add,
find
};
}

// Returns the singleton management object used to get a reference to the
// the singleton object instance
return {
getInstance: function(){
// if singleton instance does not exist, create it
if(!singletonInstance){
singletonInstance = init();
}
return singletonInstance;
}
}
})();

let firstContext = dataContextSingleton.getInstance();
firstContext.add({
id: 1,
name: 'test'
});

let secondContext = dataContextSingleton.getInstance();
let found = secondContext.find(1);

// When printed to the console, will see that the found array contains
// the object with id 1 that was added by the first reference to the
// dataContextSingleton.
console.log(found);

JavaScript: Design Patterns 05 – Controlling Global Scope Access

Controlling Global Scope Access

Utilizing the Module Patterns, we can control access to the Global Scope
in the following ways:

  • Using Modules to make everything private
  • Conditionally add elements to the Global Scope
  • Send things from the Global Scope into your custom module

This is accomplished by wrapping the library with an IIFE and anonymous function
and pass everything the library needs to run into that IIFE for use. This removes
your library completely out of the Global Scope.

(function(window, document, $){
// IIFE will execute and return an object literal
var myLibrary = (function(){

// Private scope as everything within the anonymous function is hidden
// Private variables
let _privateData = 'this is private stuff';

// Private functions
function _doSomethingPrivate(){
console.log('Just did something private.');
}

// Public API functions
function doThis(){
console.log('This was done.');
}
function doThat(){
console.log('That was done.');
doSomethingPrivate();
}

// The returned object contains the public API to the library
return {
doThis,
doThat
}

})();

// within this private scope, library api can be executed
$(document).ready(function(){
myLibrary.doThis();
myLibrary.doThat();
});

/* within this private scope, the library api can be added to the window
object so that it can be used externally.*/
if(!window.myLibrary) window.myLibrary = myLibrary;

// passing in only the Global Scope objects we need for our library to function
})(window, document, jQuery);