Javascript Mousemove Scroll Event

Sometimes you just want the window to scroll when the user moves their cursor to the top or bottom of the page. For instance, some drag and drop events block out scrolling and it is difficult for users to drag their element where they need it to go without it. Wouldn’t it be nice if we could use something to detect where the mouse is and scroll for the user automatically? Well we can! The following code insert does just that! For it, I am using angularJs events and JQuery element selection but you can use vanilla javascript to do both of these. Check this out for vanilla javascript event help and this out for DOM selection.

//call this function when we want to initiate the listener for moving the mouse
//For instance, call this function once the user starts dragging an element
function startMouseMove() {
    $document.on('mousemove', scrollWindow);
}

function scrollWindow(e) {
    const y = e.pageY; //This collects details on where your mouse is located vertically
    const container = $('.my-container'); //Replace this with the element class(.) or id(#) that needs to scroll
    const buffer = 200; //You can set this directly to a number or dynamically find some type of buffer for the top and bottom of your page
    const containerBottom = container.offset().top + container.outerHeight(); //Find the bottom of the container
    const containerTop = container.offset().top; //Find the top position of the container
    const scrollPosition = container.scrollTop(); //Find the current scroll position
    const scrollRate = 20; //increase or decrease this to speed up or slow down scrolling

    if (containerBottom - y < buffer) { //If the bottom of the container's position minus y is less than the buffer, scroll down!
      container.scrollTop(scrollPosition + scrollRate);
    } else if (containerTop + y < buffer) { //If the top of the container's position plus y is less than the buffer, scroll up!
      container.scrollTop(scrollPosition - scrollRate);
    }
}

//call this function when we want to stop the listener for moving the mouse
//For instance, call this function once the user drops a dragging element
function stopMouseMove() {
    $document.unbind('mousemove', scrollWindow);
}

Note that $document and JQuery must be declared/injected into the controller for this to work.

Happy coding!

Structure of a Program

Here is a short read to refresh on how to best structure a C++ program.

 
Structure of a program – C++ Tutorials

The best way to learn a programming language is by writing programs. Typically, the first program beginners write is a program called “Hello World”, which simply prints “Hello World” to your computer screen. Although it is very simple, it contains all the fundamental components C++ programs have:

Simple AVL Tree in C++

An AVL tree is a binary search tree(BST) however, unlike binary search trees, an AVL tree (named after Georgy Adelson-Velsky and Evgenii Landis) is self balancing. So no matter how many nodes you insert into the tree, it will adjust it’s branches and ensure the tree is balanced at all times. Making sure the subtree heights only differ by at most 1. BSTs are great for segregating and storing data with a O(log n) search time. Downside with BST is that it can get weighted on one side and doesn’t have an restrictions to prevent it from getting skewed. By switching to an AVL, data is balanced in the tree and the search time is decreased to log n.

So it is more efficient in most cases to use the AVL tree, below is an example of how to code this in C++. Note that the AVL tree uses a lot of the same code the BST did from this post.

#pragma once

#include <iomanip>
#include <iostream>

using namespace std;

class AVL
{
public:
    AVL(){
        root = nullptr;
    }
    ~AVL(){
        destroy(root);
    }
    
    //My Node class for storing data, note how I add height
    struct Node{
        int data;
        Node *left;
        Node *right;
        int height;

        Node(int d){
            data = d;
            left = nullptr;
            right = nullptr;
            height = 0;
        }

        void updateHeight(){
            int lHeight = 0;
            int rHeight = 0;
            if (left != nullptr) {
                lHeight = left->height;
            }
            if (right != nullptr) {
                rHeight = right->height;
            }
            int max = (lHeight > rHeight) ? lHeight : rHeight;
            height = max + 1;
        }

    };

    void insert(int val){
        insert(val, root);
    }

    //Rotate a Node branch to the left, in order to balance things
    Node* rotateLeft(Node *&leaf){
        Node* temp = leaf->right;
        leaf->right = temp->left;
        temp->left = leaf;

        //update the Nodes new height
        leaf->updateHeight();

        return temp;
    }

    //Rotate a Node branch to the right, in order to balance things
    Node* rotateRight(Node *&leaf){
        Node* temp = leaf->left;
        leaf->left = temp->right;
        temp->right = leaf;

        //update the Nodes new height
        leaf->updateHeight();

        return temp;
    }

    //Rotate a Node branch to the right then the left, in order to balance things
    Node* rotateRightLeft(Node *&leaf){
        Node* temp = leaf->right;
        leaf->right = rotateRight(temp);
        return rotateLeft(leaf);
    }

    //Rotate a Node branch to the left then the right, in order to balance things
    Node* rotateLeftRight(Node *&leaf){
        Node* temp = leaf->left;
        leaf->left = rotateLeft(temp);
        return rotateRight(leaf);
    }

    //Function that checks each Node's left and right branches to determine if they are unbalanced
    //If they are, we rotate the branches
    void rebalance(Node *&leaf){
        int hDiff = getDiff(leaf);
        if (hDiff > 1){
            if (getDiff(leaf->left) > 0) {
                leaf = rotateRight(leaf);
            } else {
                leaf = rotateLeftRight(leaf);
            }
        } else if(hDiff < -1) {
            if (getDiff(leaf->right) < 0) {
                leaf = rotateLeft(leaf);
            } else {
                leaf = rotateRightLeft(leaf);
            }
        }
    }

private:
    Node *root;
    //Insert a Node (very similar to BST, except we need to update Node height and then check for rebalance)
    void insert(int d, Node *&leaf){
        if (leaf == nullptr){
            leaf = new Node(d);
            leaf->updateHeight();
        }
        else {
            if (d < leaf->data){
                insert(d, leaf->left);
                leaf->updateHeight();
                rebalance(leaf);
            }
            else{
                insert(d, leaf->right);
                leaf->updateHeight();
                rebalance(leaf);
            }
        }
    }

    //Same as BST
    void destroy(Node *&leaf){
        if (leaf != nullptr){
            destroy(leaf->left);
            destroy(leaf->right);
            delete leaf;
        }
    }
    
    //Get the difference between Node right and left branch heights, if it returns positive
    //We know the left side is greater, if negative, we know the right side is greater
    int getDiff(Node *leaf){
        int lHeight = 0;
        int rHeight = 0;
        if (leaf->left != nullptr) {
            lHeight =  leaf->left->height;
        }
        if (leaf->right != nullptr) {
            rHeight = leaf->right->height
        }
        return lHeight - rHeight;
    }
};

Let me know if you have any issues!

How to do stuff RESTfully

REST, standing for Representational state transfer, it lets the browser interact with the server and get things done without knowing anything about the server, the resources it has and the background operations used to perform the requested task. I far prefer REST APIs over SOAP any day! Take a look at the RESTful cookbook below to become familiar with Howto’s and best practices. This will by far make your interactions between server and client cleaner and easier! Pretty much any website I develop, I keep REST in mind, it will make future operations and scaling smoother.

– The RESTful cookbook

REST is hot! And REST is finally rediscovered by API programmers all over the world. But REST isn’t always as easy as it seems on first look. Dealing with HATEOAS, Code on demand and uniform interfaces can be really tricky and many people will fall back to not-so-restful approaches when things are starting to become more difficult. But it doesn’t need to be. Once you get to know REST, you will like it.

Linked List Remove All

Here is a short insert on how to remove all Nodes of X value from a list. I use recursion and I believe I’ve created a pretty clean solution. This requires Nodes found in my earlier post.

#include "Node.h"

Node* head; //contains the head of our linked list

//Run the search and remove on the linked list starting at the head
//target is the value we are trying to remove from our list
void searchAndRemove(int target){
    searchAndRemove(target, head);
}


void searchAndRemove(int target, Node*& n){
    if(n != nullptr){
      if(n->data == target) { //if we found our target
        Node* temp = n;
        n = n->next; //delete and replace
        delete temp; //delete the node to clean up memory
        searchAndRemove(target, n); //continue the search, we need this to check the one used to replace
      } else {
        searchAndRemove(target, n->next); //continue the search
      }
    }
}

Let me know if you have any comments or improvements!

Binary Search Tree Traversals in C++

So this will pretty much wrap up our short expedition into binary trees. Remember that these functions rely on my earlier posts dealing with the class and nodes.

The three types of traversals we will look at are:

  • Preorder (root, left, right)
  • Inorder (left, root, right)
  • Postorder (left, right, root)

Preorder Traversal

This type of traversal can be used to create duplicates of a tree and can be used to implement prefixes. Whatever order of values you put into a tree will be the order that preorder traversal gives you. So If I enter, 5 7 4 2 1 9 8 3 6 into a binary tree, when I use preorder traversal, I will expect to see 5 7 4 2 1 9 8 3 6.

void preorderTraversal (Node* n) {
    if (n != nullptr) { //make sure we have a value
        cout << n->data << endl; //Print out the current Node value
        preorderTraversal(n->left); //traverse down the left side
        preorderTraversal(n->right); //Once we return from the left, go down the right
    }
}

Inorder Traversal

This type of traversal will return data sorted in order. So if I entered, 5 7 4 2 1 9 8 3 6, I would expect to see 1 2 3 4 5 6 7 8 9.

  void inorderTraversal (Node* n) {
    if (n != nullptr) { //make sure we have a value
        inorderTraversal(n->left); //traverse down the left side
        cout << n->data << endl; //Print out the current Node value
        inorderTraversal(n->right); //Once we return from the print, go down the right
    }
}

Postorder Traversal

This type of traversal can be used to implement postfixes and can cleanly be used to destroy a tree with out leaving Nodes floating around corrupting memory. So if I entered, 5 7 4 2 1 9 8 3 6, I would expect to see 1 3 2 4 6 8 9 7 5

 void postorderTraversal (Node* n) {
    if (n != nullptr) { //make sure we have a value
        postorderTraversal(n->left); //traverse down the left side
        postorderTraversal(n->right); //Once we return from the left, go down the right
        cout << n->data << endl; //Print out the current Node value
    }
}

For more information on binary trees, I would checkout this article. It goes into detail on how traversals on called on the tree and gives some great visuals. I also liked this interactive visual for binary search trees in general.

Good luck!

Sweet Binary Search Tree Print in C++

I found the basis of a print on Stackover flow the other day and changed it a little bit to be more compatible across compiler versions.

Happy Coding!

void print() {
    print(root, 0); //call it on your root/head node
}

For some reason my code editor wouldn’t do the left slashes so below is a screenshot.

Here is an example of what it will look like for the sequence 5 7 4 2 1 9 8 3 6: