Category Archives: Tips

Basic Git Commands

  • git init : Initialize a Git repository.
  • git status : Check the status of files and folders.
  • git add . : Tell Git to start tracking your files and folders.
  • git add app/ : Track a single folder.
  • git add config/routes.rb : Track a single file.
  • git commit -m “Initial commit” : Save the changes you made, with a message describing the changes.

  • git checkout HEAD filename: Discards changes in the working directory.

  • git reset HEAD filename: Unstages file changes in the staging area.
  • git reset commit_SHA: Can be used to reset to a previous commit in your commit history.

Git branching allows users to experiment with different versions of a project by checking out separate branches to work on. The following commands are useful in the Git branch workflow:

  • git branch: Lists all a Git project’s branches.
  • git branch branch_name: Creates a new branch.
  • git checkout branch_name: Used to switch from one branch to another.
  • git merge branch_name: Used to join file changes from one branch to another.
  • git branch -d branch_name: Deletes the branch specified.

Git Collaborative Workflow are steps that enable smooth project development when multiple collaborators are working on the same Git project:

  • git clone: Creates a local copy of a remote.
  • git remote -v: Lists a Git project’s remotes.
  • git fetch: Fetches work from the remote into the local copy.
  • git merge origin/master: Merges origin/master into your local branch.
  • git push origin : Pushes a local branch to the origin remote.

JavaScript Best Practicies : Performance Calculation

Test the speed of code with console.time

var firstRegimentNewbs = ["Grimble Horsehead", "Jark Winterborn", "Bunder Ropefist",
                          "Ernst Breadbaker"];
var firstRegimentKnights = [ *...tons of Knight objects...* ];
console.time("Time to add " + firstRegimentNewbs.length + " Knights");
for(var i = 0, x = firstRegimentNewbs.length; i

Multiple timers can run at one time.

var firstRegimentNewbs = ["Grimble Horsehead", "Jark Winterborn", "Bunder Ropefist",
                          "Ernst Breadbaker"];
var firstRegimentKnights = [ *...tons of Knight objects...* ];
var secondRegimentNewbs = ["Jenner Pond", "Tar Backstrand", "Cromer Treen", "Stim Lancetip",
                           "Vorn Sharpeye", "Rack Leaflets", "Bruck Valleyhome", "Arden Follower"];
var secondRegimentKnights = [ *...tons of Knight objects...* ];
console.time("Total completion time");
for(var i = 0, x = firstRegimentNewbs.length; i

Retrieving and using numerical time data
To accurately generate numerical data we can manipulate, we'll first examine the JavaScript Date object.
Placing a + unary operator in front of Date object variable asks for the specific value in milliseconds.

var rightNow = +new Date();

Implementation of speed test class

function SpeedTestClass(testImplementation, testParams, repetitions) {
  this.testImplementation = testImplementation;
  this.testParams = testParams;
  this.repetitions = repetitions || 10000;
  this.average = 0;
}
SpeedTestClass.prototype = {
  startTest: function() {
    var beginTime, endTime, sumTimes = 0;
    for (var i = 0, x = this.repetitions; i < x; i++){
      beginTime = +new Date();
      this.testImplement( this.testParams );
      endTime = +new Date();
      sumTimes += endTime - beginTime;
    }
    this.average = sumTimes / this.repetitions;
    return console.log("Average execution across " + this.repetitions + ": " + this.average);
  }
}

How to use created class:

var firstRegimentNewbs = ["Grimble Horsehead", "Jark Winterborn",
                          "Bunder Ropefist", "Ernst Breadbaker"];
var firstRegimentKnights = [ *...tons of Knight objects...* ];
var listsForTests = [ firstRegimentNewbs, firstRegimentKnights ];

var BP = function ( listOfParams ){
  for(var i = 0, x = listOfParams[0].length; i < x; i++) {
    listOfParams[1].push(new Knight(listOfParams[0][i], 1));
  }
};

var BPtest = new SpeedTest(noBP, listsForTests, 100000); 
BPtest.startTest();

JavaScript Best Practicies : Performance

Loop Optimization

console.log("You've found the following necklaces:");
for(var i = 0; i < treasureChest.necklaces.length; i++) {
  console.log(treasureChest.necklaces[i]);
}

For each potential loop cycle, the program will need to find and retrieve:
1. the value of i
2. the treasureChest object
3. the necklaces property
4. the array pointed to by the property
5. the length property of the array

1st optimization: Use "cached values" to curtail lengthy, repetitive access to the same data.

console.log("You've found the following necklaces:");
var x = treasureChest.necklaces.length;
for(var i = 0; i < x; i++) {
  console.log(treasureChest.necklaces[i]);
}

Memory access during loop control now only needs to:
1. retrieve the value of i
2. retrieve the value of x
Then, add in our one-time cost in creating x:
1. creating the variable x in memory.
2-5. the 4 steps finding the value of length

Some arithmetic calculations:
5 steps x (10,000 executed loops + 1 check to stop) = 50,005 memory access steps

2 steps x (10,000 executed loops + 1 check to stop) = 20,002 memory access steps
+ 5 extra steps for x = 20,007 memory access steps

~30,000 steps of savings in result!

2nd optimization: place new control variable inside the first loop parameter.

console.log("You've found the following necklaces:");
for(var i = 0, x = treasureChest.necklaces.length; i < x; i++) {
  console.log(treasureChest.necklaces[i]);
}

3rd optimization: avoid repetitive access of a property within an object

console.log("You've found the following necklaces:");
var list = treasureChest.necklaces;
for(var i = 0, x = treasureChest.necklaces.length; i < x; i++) {
  console.log(list[i]);
}

Note: Now we've avoided the extra step of accessing the treasureChest in each cycle.

Script Execution

Problem: Scripts encountered high in the or tags of an HTML page can have adverse effects.
Solution One: Scripts that are not essential to immediate loading of the page should be moved as low as possible.
Solution Two: With external files, the HTML5 async attribute will allow the rest of the page to load before the script runs.

Short Performance Tips

USE A PROTOTYPE FOR SHARED STUFF:
Beware of loading up individual objects with code that easily could be held and sourced elsewhere.
Candidate for optimization:

function SignalFire( ID, startingLogs ){ 
  this.fireID = ID;

  this.logsLeft = startingLogs;
  this.addLogs = function ( numLogs ){
 
    this.logsLeft += numLogs;

  }
  this.lightFire = function () {
 
    alert("Whoooosh!");

  }
  this.smokeSignal = function () {
    if (this.logStatus < this.message.length / 10){
      alert("Not enough fuel to send " +
             "the current message!);
    } else {
      this.lightFire();
      var x = this.message.length;
      for(var i = 0; i

Give all common methods that a "class" of objects will use to the constructor’s prototype.

function SignalFire( ID, startingLogs ){ 
  this.fireID = ID;

  this.logsLeft = startingLogs;
}

SignalFire.prototype = {
  this.addLogs = function ( numLogs ){
 
    this.logsLeft += numLogs;

  }
  this.lightFire = function () {
 
    alert("Whoooosh!");

  }
  this.smokeSignal = function () {
    if (this.logStatus < this.message.length / 10){
      alert("Not enough fuel to send " +
             "the current message!);
    } else {
      this.lightFire();
      var x = this.message.length;
      for(var i = 0; i

USE A DOCUMENT FRAGMENT TO INSERT ADDITIONS ALL AT ONCE:
Adding DOM elements individually ain't always speedy, since each new addition to the DOM causes document "reflow", which can really hinder user experience.

var list = document.getElementById("kotwList");
 
var kotw = ["Jenna Rangespike", 

            "Neric Farthing",
            "Darkin Stonefield"];
for (var i = 0, x = kotw.length; i

Note: Each time the list is appended, we access the DOM and cause an entire document reflow. Not as speedy as we’d like, especially if our list was huge...

Solution:
Use a document fragment to insert additions all at once. Fragments are invisible containers that hold multiple DOM elements without being a node itself.

var list = document.getElementById("kotwList");
 
var kotw = ["Jenna Rangespike", 

            "Neric Farthing",
            "Darkin Stonefield"];
var fragment = document.createDocumentFragment();
for (var i = 0, x = kotw.length; i

Note: Now we add each new li element to the staging fragment, instead of to the document itself. And append all of our new text nodes in one fell swoop, using only one DOM touch!

DECLARE VARIABLES AS FEW TIMES AS POSSIBLE
Every var keyword adds a look-up for the JavaScript parser that can be avoided with comma extensions. Commas used after an initial declaration can signal that you'll declare further variables.

Declaring in loops should thus be used with caution. Anticipate variable needs to avoid the processor burden of creating a new var over and over.

According to all these statements code transforms to:

var list = document.getElementById("kotwList"),
    kotw = ["Jenna Rangespike", 

            "Neric Farthing",
            "Darkin Stonefield"],
    fragment = document.createDocumentFragment(),
    element;
for (var i = 0, x = kotw.length; i

EFFICIENT CHOICES FOR STRING CONCATENATION
Different string building methods will yield different results in terms of execution speed.

The standard concatenation operator has been optimized in most modern browser versions, and is an ideal choice for a small number of string concatenations.

var turn = "";
turn += knight;
turn += action;
turn += weapon;

For concatenations over an array's contents, use the join() method inherited from the Array prototype.

var newPageBuild = [ "", "", "", "

",! ***a hundred or more other html elements***,! "", “", "" ]; page = newPageBuild.join("\n");

Note: The join method concatenates each index of the array, "joined" by any string parameter you pass in. In addition to being faster in tests than many String methods, it is also easier to read.

JavaScript Best Practicies : Syntax

Ternary Conditionals

isArthur && isKing ? 
    (weapon = "Excalibur", helmet = "Goosewhite") : 
        isArcher ? (weapon = "Longbow", helmet = "Mail Helm") : 
        (weapon = "Longsword", helmet = "Iron Helm");;

The “OR” Operator

  • When used in assignment, the OR operator will try to select the first value it encounters that is not “false”.
  • The OR operator takes the leftmost “truth” value, and if none exists, the last “false” value.
var result1 = undefined || 42;
console.log(result1); // 42

var result2 = 0 || ["Item1", "Item2"];
console.log(result2); // ["Item1", "Item2"]

var result3 = "" || {type: "Type", item: "Item"};
console.log(result3); // {type: "Type", item: "Item"}

When all elements are “true”, the FIRST “true” value assigned.

var result1 = "Value" || "Item";
console.log(result1); // "Value"

When all elements are “false”, the LAST “false” value assigned.

var result1 = undefined || "";
console.log(result1); // ""

The “AND” Operator

  • The && operator takes the rightmost “truth” value or the first “false” value.
var result1 = undefined && 42;
console.log(result1); // undefined

var result2 = 0 && ["Item1", "Item2"];
console.log(result2); // 0

var result3 = "" && {type: "Type", item: "Item"};
console.log(result3); // ""

When all elements are “true”, && will return the LAST “true” value found.

var result1 = "Value" && "Item";
console.log(result1); // "Item" 

The Switch Block

function Knight (name, regiment){
 
this.name = name;
 
this.regiment = regiment;
switch (regiment) {

  case 1:

    this.weapon = "Broadsword";
    break;

  case 2:

    this.weapon = "Claymore";
    break;

  case 3:

    this.weapon = "Longsword";
    break;
  case 5:

    this.weapon = "War Hammer";
    break;
  case 6:

    this.weapon = "Battle Axe";
    break;
  case 4:
 
  case 7:
 
  case 8:
    this.weapon = "Morning Star";
    break;
  case "King":"
    this.weapon = "Excalibur";
    break;
  default:
    alert(name + " has an incorrect " + "
        "regiment, Master Armourer!" + "
        "\n\nNo weapon assigned!");

A carefully organized switch block can add LEAST common properties first and MOST common, last.

function ceremonialDagger(knight, rank){
	this.length = 8;
	this.owner = knight;
	switch(rank){
	  case "King": this.diamonds = 1;
	  case "High Constable": this.amethyst = 2;
	  case "Field Marshal": this.sapphires = 4;
	  case "Captain": this.emeralds = 1;
	  case "Knight": this.rubies = 6;
  	}
}

var marshalsDagger = new ceremonialDagger("Timothy", "Field Marshal");
console.log(marshalsDagger); // ceremonialDagger {length: 8, owner: "Timothy", sapphires: 4, emeralds: 1, rubies: 6}

Text tricks

Have you ever need to parse the text into the words? You can use the following code:

$result = preg_split('/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/', $text, -1, PREG_SPLIT_NO_EMPTY);

And a task which based on previous code:
Find the frequency of defined word anagrams in the whole text.


Some improvements, you can read text and defined word from command line.
The final code:

if (count($argv) < 2) {
    die('You should specify the file and the word');
}

$text = file_get_contents($argv[1]);
$word = trim($argv[2]);

$dict = array();

$sort = function($string) {
    $stringParts = str_split($string);
    sort($stringParts);
    return implode('', $stringParts);
};

$result = preg_split('/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/', $text, -1, PREG_SPLIT_NO_EMPTY);

if (count($result) > 0) {
    foreach($result as $value) {
        $dict[$sort($value)]++;
    }
    
    //Print frequency
    echo $dict[$sort($word)];
} else {
    echo 'Text is empty';
}

Шаблоны проектирования

JavaScript, будучи динамическим нетипизированным языком, опирающимся на использование прототипов, иногда позволяет удивительно легко и даже тривиально реализовать шаблоны проектирования.

Continue reading

Основные приемы и шаблоны JavaScript

  • Снижение количества глобальных переменных, в идеале – не более одной на приложение.
  • Использование единственного объявления var в функциях, что позволяет одним взглядом охватить все переменные и предотвращает появление неожиданностей, вызванных особенностями механизма подъема переменных.
  • Циклы for (использовать только для массивов), циклы for-in (использовать только для объектов), инструкции switch, «eval() – это зло», нежелательность расширения прототипов.
  • Следование соглашениям по оформлению программного кода (последовательное использование пробелов и отступов; использование фигурных скобок и точек с запятой даже там, где они являются необязательными) и соглашениям по именованию (конструкторов, функций и переменных).

Необходимо стремиться свести к минимуму операции обращения к дереву DOM. Это означает, что:

  • Следует избегать обращений к элементам DOM внутри циклов
  • Желательно присваивать ссылки на элементы DOM локальным переменным и работать с этими переменными
  • Следует использовать интерфейс селекторов, где это возможно
  • Следует сохранять значение свойства length в локальной переменной при выполнении итераций через коллекции HTML

Стараться свести к минимуму количество операций, модифицирующих дерево DOM, что означает накапливать изменения, выполняя их за пределами «живого» дерева DOM документа.

CSS transition trick