Wednesday, November 9, 2016

[PHP] Implement Binary Tree


class Node
{
    public $value, $left, $right;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

Search:
class BST
{
    public $root;

    public function __construct($value = null)
    {
        if ($value !== null) {
            $this->root = new Node($value);
        }
    }

    public function search($value)
    {
        $node = $this->root;

        while($node) {
            if ($value > $node->value) {
                $node = $node->right;
            } elseif ($value < $node->value) {
                $node = $node->left;
            } else {
                break;
            }
        }

        return $node;
    }
}

Insertion:
public function insert($value)
{
    $node = $this->root;
    if (!$node) {
        return $this->root = new Node($value);
    }

    while($node) {
        if ($value > $node->value) {
            if ($node->right) {
                $node = $node->right;
            } else {
                $node = $node->right = new Node($value);
                break;
            }
        } elseif ($value < $node->value) {
            if ($node->left) {
                $node = $node->left;
            } else {
                $node = $node->left = new Node($value);
                break;
            }
        } else {
            break;
        }
    }
    return $node;
}


Min:
public function min()
{
    if (!$this->root) {
        throw new Exception('Tree root is empty!');
    }

    $node = $this->root;
    return $node->min();
}

public function min()
{
    $node = $this;
    while ($node->left) {
        if (!$node->left) {
            break;
        }
        $node = $node->left;
    }
    return $node;
}

Max:
public function max()
{
    if (!$this->root) {
        throw new Exception('Tree root is empty!');
    }

    $node = $this->root;
    return $node->max();
}

public function max()
{
    $node = $this;
    while ($node->right) {
        if (!$node->right) {
            break;
        }
        $node = $node->right;
    }
    return $node;
}


Bash command redirections

There are 3 file descriptors, stdin, stdout and stderr (std=standard).

Available options:
  1. redirect stdout to a file
  2. redirect stderr to a file
  3. redirect stdout to a stderr
  4. redirect stderr to a stdout
  5. redirect stderr and stdout to a file
  6. redirect stderr and stdout to stdout
  7. redirect stderr and stdout to stderr
  8. 1 'represents' stdout and 2 stderr.
Note: with the less command you can view both stdout (which will remain on the buffer) and the stderr that will be printed on the screen, but erased as you try to 'browse' the buffer.

Sample: stdout to file

This will cause the ouput of a program to be written to a file.

         ls -l > stdout.txt
        
Here, a file called 'stdout.txt' will be created and it will contain what you would see on the screen if you type the command 'ls -l' and execute it.

Sample: stderr 2 file

This will cause the stderr output of a program to be written to a file.

          ls -l 2> stderr.txt
        
Here, a file called 'stderr.txt' will be created and it will contain what you would see the stderr portion of the output of the ' ls -l' command.

Sample: stdout 2 stderr

This will cause the stderr ouput of a program to be written to the same filedescriptor than stdout.

          ls -l 1>&2 
        
Here, the stdout portion of the command is sent to stderr, you may notice that in different ways.

Sample: stderr 2 stdout

This will cause the stderr ouput of a program to be written to the same filedescriptor than stdout.

          ls -l 2>&1
        
Here, the stderr portion of the command is sent to stdout, if you pipe to less, you'll see that lines that normally 'dissappear' (as they are written to stderr) are being kept now (because they're on stdout).

Sample: stderr and stdout 2 file

This will place every output of a program to a file. This is suitable sometimes for cron entries, if you want a command to pass in absolute silence.

          ls -l &> /dev/null 
        
This (thinking on the cron entry) will delete every file called 'core' in any directory. Notice that you should be pretty sure of what a command is doing if you are going to wipe it's output.

Running background jobs in Unix

When you execute a Unix job in the background ( using '&', 'bg' command), and logout from the session, your process will get killed.

You can avoid this by executing the job with 'nohup' (stands for no hang up).

Usage:
nohup {command-with-options} &

'nohup' is very helpful when you have to execute a shell-script or command that take a long time to finish. In that case, you don’t want to be connected to the shell and waiting for the command to complete. Instead, execute it with nohup, exit the shell and continue with your other work.

Explanation about nohup.out file:
By default, the standard output will be redirected to nohup.out file in the current directory. And the standard error will be redirected to stdout, thus it will also go to nohup.out. So, your nohup.out will contain both standard output and error messages from the script that you’ve executed using nohup command.

Difference between .bash_profile & .bashrc

WHEN working with Linux, Unix, and Mac OS X, I always forget which bash config file to edit when I want to set my PATH and other environmental variables for my shell. Should you edit .bash_profile or .bashrc in your home directory?

You can put configurations in either file, and you can create either if it doesn’t exist. But why two different files? What is the difference?
According to the bash man page, .bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.

What is a login or non-login shell?
When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt.
But, if you’ve already logged into your machine and open a new terminal window (xterm) inside Gnome or KDE, then .bashrc is executed before the window command prompt. .bashrc is also run when you start a new bash instance by typing /bin/bash in a terminal.

Why two different files?
Say, you’d like to print some lengthy diagnostic information about your machine each time you login (load average, memory usage, current users, etc). You only want to see it on login, so you only want to place this in your .bash_profile. If you put it in your .bashrc, you’d see it every time you open a new terminal window.

Mac OS X — an exception
An exception to the terminal window guidelines is Mac OS X’s Terminal.app, which runs a login shell by default for each new terminal window, calling .bash_profile instead of .bashrc. Other GUI terminal emulators may do the same, but most tend not to.

My Recommendation
Most of the time you don’t want to maintain two separate config files for login and non-login shells — when you set a PATH, you want it to apply to both. You can fix this by sourcing .bashrc from your .bash_profile file, then putting PATH and common settings in .bashrc.

To do this, add the following lines to .bash_profile:
if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

Now when you login to your machine from a console .bashrc will be called.

[PHP] Send attachment in mail


date_default_timezone_set('America/Los_Angeles');

// Create a file with data to send
$file_name = "summary.txt";
$myfile = fopen($file_name, "w") or die("Unable to open file!");
$txt = "PHP Mail function example with attachment" . PHP_EOL;
fwrite($myfile, $txt);
fclose($myfile);

$filetype = filetype($file_name);

//read from the uploaded file & base64_encode content for the mail
$content = file_get_contents($file_name);
$encoded_content = chunk_split(base64_encode($content));

$boundary = md5("php-mail");

$from_email = 'from_email@gmail.com'; //sender email
$recipient_email = 'recipient_email@gmail.com'; //recipient email
$subject = 'Test mail'; //subject of email
$message = 'This is body of the message'; //message body

//header
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From:".$from_email."\r\n";
$headers .= "Reply-To: ".$from_email."\r\n";
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

//plain text
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode($message));

//attachment
$body .= "--$boundary\r\n";
$body .="Content-Type: $filetype; name=\"$file_name\"\r\n";
$body .="Content-Disposition: attachment; filename=\"$file_name\"\r\n";
$body .="Content-Transfer-Encoding: base64\r\n";
$body .="X-Attachment-Id: ".rand(1000,99999)."\r\n\r\n";
$body .= $encoded_content;

$sentMail = mail($recipient_email, $subject, $body, $headers);
if($sentMail) //output success or failure messages
{    
    die('Thank you for your email');
} else {
    die('Could not send mail! Please check your PHP mail configuration.');
}

[PHP] Convert command line parameters to array

When we write a script which will be run from command line, we may have a need to pass in certain input params. This is similar to the GET/POST parameters that a web page uses as input params.

The function below is an easy way to convert the command line input params and use it like an array in the script.

// Convert arguments to key/value pairs, like the $_GET or $_POST arrays
$args = array();
foreach ($argv as $arg) {
    if ($pos = strpos($arg, '=')) {
        $key = substr($arg, 0, $pos);
        $value = substr($arg, $pos+1);
        $args[$key] = $value;
    }
}

Input:
php run_my_script.php key1=value1 key2=value2 key3=value3

Output:
$args = [
    'key1' => value1,
    'key2' => value2,
    'key3' => value3,
];

[PHP] Implement Stacks (LIFO)


class ReadingList
{
    protected $stack;
    protected $limit;
    
    public function __construct($limit = 10) {
        // initialize the stack
        $this->stack = array();
        // stack can only contain this many items
        $this->limit = $limit;
    }

    public function push($item) {
        // trap for stack overflow
        if (count($this->stack) < $this->limit) {
            // prepend item to the start of the array
            array_unshift($this->stack, $item);
        } else {
            throw new RunTimeException('Stack is full!'); 
        }
    }

    public function pop() {
        if ($this->isEmpty()) {
            // trap for stack underflow
          throw new RunTimeException('Stack is empty!');
      } else {
            // pop item from the start of the array
            return array_shift($this->stack);
        }
    }

    public function top() {
        return current($this->stack);
    }

    public function isEmpty() {
        return empty($this->stack);
    }
}


Output:
$myBooks = new ReadingList();

// add some items to the stack
$myBooks->push('A Dream of Spring');
$myBooks->push('The Winds of Winter');
$myBooks->push('A Dance with Dragons');
$myBooks->push('A Feast for Crows');
$myBooks->push('A Storm of Swords'); 
$myBooks->push('A Clash of Kings');
$myBooks->push('A Game of Thrones');

// remove some items from the stack
echo $myBooks->pop(); // outputs 'A Game of Thrones'
echo $myBooks->pop(); // outputs 'A Clash of Kings'
echo $myBooks->pop(); // outputs 'A Storm of Swords'

// top of the stack
echo $myBooks->top(); // outputs 'A Feast for Crows'

[PHP] Implement Linked List


/**
 * Class Node
 */
class Node
{
    public $data;
    public $next;

    public function __construct($item)
    {
        $this->data = $item;
        $this->next = null;
    }
}

/**
 * Class LinkList
 */
class LinkList
{
    public $head = null;

    private static $count = 0;

    /**
     * @return int
     */
    public function GetCount()
    {
        return self::$count;
    }

    /**
     * @param mixed $item
     */
    public function InsertAtFist($item) {
        if ($this->head == null) {
            $this->head = new Node($item);
        } else {
            $temp = new Node($item);

            $temp->next = $this->head;

            $this->head = $temp;
        }

        self::$count++;
    }

    /**
     * @param mixed $item
     */
    public function InsertAtLast($item) {
        if ($this->head == null) {
            $this->head = new Node($item);
        } else {
            /** @var Node $current */
            $current = $this->head;
            while ($current->next != null)
            {
                $current = $current->next;
            }

            $current->next = new Node($item);
        }

        self::$count++;
    }

    /**
     * Delete the node which value matched with provided key
     * @param $key
     */
    public function Delete($key)
    {
        /** @var Node $current */
        $current = $previous = $this->head;

        while($current->data != $key) {
            $previous = $current;
            $current = $current->next;
        }

        // For the first node
        if ($current == $previous) {
            $this->head = $current->next;
        }

        $previous->next = $current->next;

        self::$count--;
    }

    /**
     * Print the link list as string like 1->3-> ...
     */
    public function PrintAsList()
    {
        $items = [];
        /** @var Node $current */
        $current = $this->head;
        while($current != null) {
            array_push($items, $current->data);
            $current = $current->next;
        }

        $str = '';
        foreach($items as $item)
        {
            $str .= $item . '->';
        }

        echo $str;

        echo PHP_EOL;
    }
}

$ll = new LinkList();

$ll->InsertAtLast('KP');
$ll->InsertAtLast(45);
$ll->InsertAtFist(11);
$ll->InsertAtLast('FE');
$ll->InsertAtFist('LE');
$ll->InsertAtFist(100);
$ll->InsertAtFist(199);
$ll->InsertAtLast(500);

$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(45);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(500);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(100);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;

Output:
$ php LinkList.php
199->100->LE->11->KP->45->FE->500->
Total elements 8
199->100->LE->11->KP->FE->500->
Total elements 7
199->100->LE->11->KP->FE->
Total elements 6
199->LE->11->KP->FE->
Total elements 5