"The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The constructors for Collator, NumberFormat, and DateTimeFormat objects are properties of the Intl object. This page documents these properties as well as functionality common to the internationalization constructors and other language sensitive functions."
"The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The constructors for Collator, NumberFormat, and DateTimeFormat objects are properties of the Intl object. This page documents these properties as well as functionality common to the internationalization constructors and other language sensitive functions."
A story loosely based in the Stone Age which explores more than just hunting, gathering and survival in a prehistoric setting. It's about the significance of belonging and building relationships in a tribe. The development of the main protagonist from a young naive girl – who only knows a life of solitude with her father – into a mature young woman that must understand the importance of social dynamics and responsibility.
Her father Torion has taught her all she knows. She's an agile and adept spear thrower, but there is more to survival than that. She finds this out once torn apart from her home and her father, forced to fend for herself in a prehistoric world. The Ursa hunters; the fierce clan who are out to get her, are big in numbers and a huge threat to her and the tribes across the land.
Adira must reluctantly form relationships with others in the hope to find her father and fight back against the imposing threat. With the discovery of her past coming to light throughout her journey, she must decide what life she wants to lead.
Read the full story in ebook, paperback or hardback.Nutmeg Frontend Architecture & Testing - Remote TalkSMKS2020-05-11 | As Frontend Platform Lead at Nutmeg, Shaun is responsible for the architecture of the Frontend. He's helped lead the launch of Nutkit, a bespoke design system that powers the visuals of all the web applications at Nutmeg. Shaun is an advocate of automation, testing, UI consistency and quality control. With a passion for writing, he's written trending articles such as, 'These are the reasons Software Engineers don't leave their jobs' and is the author of the popular book 'Automating with Node.js', and most recently 'Software Engineers do what now?'
TITLE OF TALK: Frontend Architecture & Testing at Nutmeg
TOPICS TO COVER: 1. Introduction 2. Ruby to React 3. Design System - Nutkit (Design tokens, Storybook) 4. Web Libraries (Business components) 5. Applications (SPA) 6. Unit Testing - Jest + Enzyme 7. Integration Testing - Web Libraries 8. End to end - Cypress 9. Visual Regression - Loki 10. Q&ASoftware Engineers do what now? Learning how to codeSMKS2020-02-15 | With this book, we’ll introduce you to the variety of technical roles out there, the recruitment process, the positions that exist on the career ladder and make our way through an abundance of sought after technical languages, tools, libraries and frameworks that companies seek from candidates today.
Anyone can code if they put their mind to it. Yep, I said it. It’s always perceived as something really difficult. If you invest time to understand it, build things and identify problems early, you will grow, become less frustrated and eventually see the fun/rewarding side of it.
Good skills to have Some good skills to have as a programmer: 1. Patience - Have the tenacity to keep working through challenges 2. Inventive - Thinking of better/faster ways to work effectively 3. Problem-solving - Think through solutions and choose the best one 4. Communication - To avoid mistakes, speed up development and increase morale 5. Collaboration - Innovation is so much better when working as a team 6. Persistence - Don’t let problems defeat you, keep going 7. Humility - Be receptive to criticism and other people’s ideas 8. Helpful - Help others having issues, even if they are obvious/overlooked 9. Adaptive - The tech world changes quite fast, keep learning 10. Respectful - Don’t rewrite your teammate’s code without a discussion beforehand
Ways to learn to code
There are two ways of learning, and both are equally as important.
A - Reading about code When you open up a book on a train and flick through the pages of code examples and nod your head to say, ‘Aha, so that’s how you do that thing’, you’re building up your understanding of that language on an intellectual level only. Reading alone is not enough. If an employer sat you in front of a computer, you would not know what on earth to do, even if you had read ten books on the subject. Musicians can’t learn their instruments without playing the darn thing over and over again, and this brings us onto ‘acting on code.’
B - Acting on code When you are at home on a laptop or PC, and you have a text editor open, and you actively follow along by writing the code of a book or online course and confirm what you’ve written in the editor works, you are building up knowledge through the repetition of keystrokes. When something in your code fails and you are sitting there scratching your head in dismay, but you eventually work out what went wrong, if it happens again, you know how to tackle it, making you wiser and more experienced. This sums up my career in a nutshell, to be honest.
In my experience, I tend to read books on theory. But any new programming languages or libraries I need to know, I will act on learning material by writing out the examples. Theory can be applied to any programming language.
The games I’ve built in the past would introduce fresh new problems that I’d never come across before. The experience I’ve gained on personal projects on how to code is phenomenal.Automating with Node.js - 001SMKS2018-07-15 | Book on Amazon: http://amzn.eu/1dxeQp4 Leanpub: leanpub.com/automatingwithnodejs
Video based on the popular 'How I automated my job with node.js' article on Medium.
Node.js was designed by Ryan Dahl and released in May 2009. It’s a way to execute JavaScript code server-side as opposed to the traditional client-side approach.
Whenever you think of JavaScript, you usually think of using it in a web browser. This is referred to as client side scripting. You: open up a new browser window, make a request to your favourite web page where the HTML and CSS gets rendered, and then JavaScript files get loaded and executed to provide dynamic functionality on the page. All browsers have a JavaScript engine that interprets the JavaScript you execute in that browser.
A well known JavaScript engine supported by Chrome called V8 interprets JavaScript in the browser, and is also used by node. Once you’ve installed node onto your computer, when you open up a CLI and type node, you are interacting with the node executable installed on your machine. When you pass a JavaScript file to it, the node executable behind the scenes uses V8 to interpret the script.
The first thing we are going to do is to create a JavaScript file called hello.js. In this file we are simply going to pass our name as a string argument, and allow the node executable to return us some output saying hello. I know… advanced stuff, right? This will give us an understanding of how we start using node in the context of creating a CLI application.
The first line we are going to create will declare a constant called args, where we pass process.argv. Now, what is this process object we have here? And what is this argv value? The process object in the context of node is a global that provides information about, and control over the current Node.js process. We will go into more detail in another video on the process object, but for now, we just want to know about one of its properties called argv.
The argv property is an array that holds information about what was passed in the CLI. The first two elements by default are: the path to the node executable; and the second, a path to the JavaScript file you are interpreting. Anything else passed in the CLI such as a string argument will be pushed on to the end of the array as a new element. So if I did: node hello.js “Shaun”, then, “Shaun” would be the third element of the array.
We want to output back to the user their name when we decide to be friendly and greet them. How can we do this? We simply create a new constant called name, and assign it from the third element of the array. As we will not make any use of the first two elements in the array, we remove them by applying a slice operation. This means we only have one element left, and we assign the name as the first element of the array.
If the user does not pass a string with their name, we want to check this and return a message telling them that this is not a negotiation. We want your name, otherwise you are unfortunately not getting a greeting. We can check if they didn’t pass a string argument by checking if the value is undefined. If it is, then we log a message to the user and exit the process. If however, they have decided to be generous and provide their name, we simply log out our friendly greeting back to the user.
Once the script reaches the end of the execution, the process is then exited and removed from the Operating system’s currently running processes.Automating with Node.jsSMKS2018-06-09 | A new video course based on the book is coming soon!
Popular blog post (Number 4/10 on top Node articles of the month): medium.com/dailyjs/how-i-automated-my-job-with-node-js-94bf4e423017Clean Code - JavaScriptSMKS2017-11-12 | This video delves into the subjective idea of writing clean code. From experiencing similar problems in my own career, it's good to shed a light on some things that could potentially help your own team so that the code you work with is consistent and easily interpreted going forward.
Writing clean code is a benefit both to you and your co-workers. Why? Can you remember a time when you carried out a code review and had to question what was happening in a specific function. If you have, then it means the code probably could’ve been cleaner. It’s something we should aspire to do.
To quote Robert C. Martin, “...Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.” To start, let’s begin by asking what isn’t clean code? Our examples will be based around JavaScript.
Magic numbers - Assigning a number that has no clear meaning. It’s better to replace with a named constant.
Deep nesting - If your code contains many nested loops or conditional statements, then this should probably be extracted into a separate function.
Avoid large functions - A function or even a class that is large in size suggests that it’s doing more than it should. Code repetition - If you have to copy and paste a block of code, it’s a sign that that the repeated block may need to be extracted into its own function.
Complex expressions - A function that is carrying out some computation, but it’s unclear what’s being computed.
So what are some of the things you can start doing to make it easier for you and your team? Let’s start with simple naming conventions.
A variable name should be intention-revealing. If you want to store a count of eggs don’t create a variable called ‘EC’, use something meaningful, such as ‘egg count’. A function should be a verb or a verb phrase, and must communicate its intent. A shortened method name causes more hassle than the keystrokes you save in the long run. If you need to pass a huge list of arguments into a function, use a single object parameter instead. It’s advised to have no more than two or three arguments.
To make it more natural when reading the source code, organise your script with higher level functions at the top and lower level functions beneath, making it more natural to read through. Agree on a coding standard in your team so that every script written is consistently formatted. Airbnb and Google have a coding standard they favor with ESLint. Following these rules will save a lot of debate, and even if your team all agree on a convention, such as replacing indentation from 2 to 4, this can be overridden in the configuration.
Although subjective, the use of comments in your code can be helpful, but could be a sign your code is failing to be self explanatory.
To summarise, there are huge benefits to following these rules in the long run. Others may pick up the code you’ve written in a few days, months or even years, scan from top to bottom, and either sigh of relief or frustration. Which one would you prefer?How to Code - JavaScript Apply & CallSMKS2016-12-05 | Code Snippet: gist.github.com/smks/84e2a8c6fdf4488077857f0477c9e927
Learn the difference between apply and call.
"One of the trickier bits of the language is learning the differences between JavaScript apply vs. call vs. bind. All three of these JavaScript methods allow you to change the value of this for a given function."
"bind() allows us to easily set which specific object will be bound to this when a function or method is invoked."
"The need for bind usually occurs when we use the this keyword in a method and we call that method from a receiver object; in such cases, sometimes this is not bound to the object that we expect it to be bound to, resulting in errors in our applications"
The let statement declares a block scope local variable, optionally initializing it to a value.
Constants are block-scoped, much like variables defined using the let statement. The value of a constant cannot change through re-assignment, and it can't be redeclared.
"A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise for the value at some point in the future."
A demonstration on how to use the Fetch API with JavaScript. A much simpler approach to making a XMLHttpRequest/AJAX call.
http://www.opencanvas.co.uk (To use the API URL used in the video for your own learning set date to today's date UK time)
Open up your Chrome browser and open Dev Tools, navigate to the Console tab and follow along with the example!
References:
developers.google.com/web/updates/2015/03/introduction-to-fetch https://davidwalsh.name/fetchHow Web Browsers FunctionSMKS2016-11-06 | This video explains the process behind a web browser. What happens when you enter a URL and press enter, and how does the browser know how to present the page to you? This is all explained, as well as all the components that make up a web browser.
We use web browsers every day to display web pages, but have you ever wondered what is happening behind the scenes? This is the basic flow of viewing a web page: you send a request over the network to a server, it responds with a collection of web content as a response. Your browser interprets the content returned and displays the page. Let’s look at a high level structure of a browser and the components it uses to accomplish this:
The user interface is what’s presented to the user to interact with. It displays to you the address bar, back and forward buttons and any other visual element you can interact with, such as tabs. A browser has a rendering engine that is responsible for displaying the visual representation of the webpage. Think of the rendering engine as a painter working on a blank canvas. It’s his responsibility to construct the page by applying the right structures and colours.
The engine takes in HTML and CSS documents, then displays its interpretation of both. HTML exists to markup our content, and CSS is used to style and animate our content. The browser engine acts as a marshal who directs actions between the User Interface and the rendering engine, as well as external communication with servers.
To receive content for a web page, the browser has to communicate over the network, asking for all the necessary images and documents that make up the page. You’ve probably encountered a situation where an image is missing on the page, this usually means the network failed to fetch the image from the server. ((demo ajax request in animation))
To apply interactive logic and functionality to our website, we rely on a programming language called JavaScript. The browser has no idea how to deal with JavaScript directly. It’s like a person who only knows Spanish, but is trying to listen to someone speaking Chinese. We need a way to translate the communication, and this is done with an interpreter. Browsers have their own JavaScript interpreters: Chakra is used by Microsoft Edge, SpiderMonkey for Firefox and V8 is used by Google Chrome.
You also have something called data storage such as Cookies and Local Storage. This helps us retain state even when you refresh the page. You’ll find cookies are used to remember bits of information such as your name.
The rendering engine can render images, videos, SVG files, audio files, but by default; displays HTML and XML documents; types of markup language. These documents as you can see are constructed of tags. Not all browsers use the same rendering engine. This is why you sometimes see inconsistencies with how things look from browser to browser. Chrome and Opera use an engine called Blink, Safari uses WebKit and Firefox uses Gecko. These engines have their own implementations of how to render the page, but all tend to follow the same flow.
It’s the responsibility of the network layer to provide the rendering engine the requested document. Firstly, the rendering engine reads the HTML and constructs a DOM content tree, this stands for ‘Document Object Model’; an object representation of the HTML document. The DOM tree is made up of DOM nodes. Nodes can be images, text blocks, buttons or any other element.
All the CSS styling associated with these nodes are parsed by the engine. Now with the styling information and visual instructions, a new tree can be created; the render tree. Once this has been constructed, it then goes through a layout process where each node is positioned on the screen with coordinates. The render tree is then traversed, with each node painted using the UI backend layer. The process happens so fast, you can’t see every node get rendered on the page, hence why the whole page’s entire content is visible when the page has finished loading.
When the parsing process has finished, the browser will mark the document as interactive, allowing you; the user, to interact with the nodes on the page.
In this lesson, we are going to cover the object oriented concept of ‘Inheritance’ when working with our code. Now although it can be considered a good approach for code reuse, it’s not always the way to go, for reasons we will discuss later on. But for now, let’s use the game example of constructing a hypothetical player for our game called Riley, just to put it into practice.
For now and future lessons, we will be migrating from the Action script language, to Haxe (HACKS) and the OpenFL (OPEN F. L.) Flash API. Links can be found in the description. First of all, we want our player to have the properties: name, and the direction he is currently facing.
Lets give this player some methods: stand, walk and talk. Now in our main class - which is called first on compilation - we can create a new instance of Riley and call the methods. First we call talk, that requires no parameters. Then stand, passing in the parameter of the direction. Finally, walk, passing in the number of steps to take and in what direction.
When we build this project with the HTML5 target, we can see in the console our traced output. Great, so we've built a class and made a new instance of it. But with this game, we have two protagonists, and we've only built a class for one of them. We also need one for Jack. The exact same functionality is required. We want Jack to stand, walk and talk. So our first instinct is to create a new class called Jack, copy everything from Riley, and paste it into Jacks class file. We create a new instance of Jack, and we can see that we get the expected behavior in the console. The thing is, they both share the exact same code, the only differences between them, is their name. Riley, and Jack. Duplicate code exists, and you could see how this would be an issue if we introduced more protagonists. So what would be a possible solution to this? We can make use of ‘Inheritance’. With this, we can specify a ‘super class’ that both players can ‘extend’ from.
So first things first. Let’s create the super class. In this class, we want all the code that is relevant to both protagonists. We will call this super class ‘Player’. We copy and paste all the code from one of the existing players, and tweak it so it’s relevant. In this case, it’s not setting the name so we initialize it, but don’t set it. Now if we go back to our Jack and Riley classes, we can remove all the boilerplate code, leaving behind the constructor function and make the name change. When we call super in the constructor, it will call the constructor of its parent, this means we don’t have to trace the name of the player and the direction they are currently facing. Remember to call the super method after you have declared your attributes in the sub class. When we have made this change for both sub classes: Riley and Jack, you’ll see that even if we call them, they both work like before, as seen in the console.
As mentioned earlier, Inheritance can be suitable in some cases, and does promote code reuse and code organisation, but isn't always suitable. You’d usually begin each coding problem by constructing some form of inheritance hierarchy that may not actually be suitable for that certain situation. An example being a zoo park, with many types of animals. Your task is to design a class for each animal in that park, taking into account their attributes and behaviors. They have a tiger and a lion that can both jump. So you create a super class named Animal with a method ‘jump’ to cater for them both. We can now make a tiger and lion class, and extend from the animal super class. But what about an elephant? They can’t jump, so if we create a new elephant class and extend from animal, it’s not relevant. In a situation like this, we need to consider ‘Composition over Inheritance’, something we will discuss in the next lesson.
Lesson 4 delves into file and directory permissions and the 9 RWX bits associated with each.
So here’s a scenario; your root admin has created you as a new user on the system at a company you work for. You have created some important files related to your business on the system, and it’s paramount that these files aren’t tampered with. But someone from another department needs to read the files for verification. Ideally we want them to read the file, but not modify anything. Or how about you’re a web developer, and you have a directory of file scripts you want to share with your team, but no-one else.
By setting file or directory permissions, we can determine what user’s can read, write or even execute. With linux, we can set permissions to do just that. The nine bits assigned to each file or directory define the access that you and the others have. The first 3 bits apply to the owner’s permission. The next three apply to the group assigned and the last 3 apply to all others.
The R stands for read, with a file this means you can view the contents of the file and with a directory, you can see what files and subdirectories it contains. The W stands for write, meaning a file’s contents can be changed, the file can be renamed or even deleted. If it’s a directory, it means you can add, change or delete files or subdirectories in that directory. The X stands for Execute. With a file it will be treated as a program and run. With a directory, you can change to it, search or execute a program from that directory.
If a dash appears instead of the letter, it means the permission is turned off for that associated read, write, or execute bit. At any time you can identify the permissions for any file or directories in your present working directory by typing: LS -LD We can see the 9 bit permissions associated with each. In most cases, unless you are the root admin, your ability to alter permissions will be limited. If you own a file, you can use the CHMOD command to alter the permissions as you wish.
The CHMOD command can change permissions with either numbers or letters. In our example we will be using numbers. With numbers, each permission is assigned a number, and you use each set’s total number to establish the permission.
For example, you have written a bash script, and you only want you and your team to be able to execute it. You could apply permissions to it by typing: CHMOD 750 (followed by the filename). This gives you; the owner, full permissions and your group the ability to read and execute, but not write. All others are entirely prohibited. Permissions can also be applied to a directory recursively, meaning that it will apply the permission to all files and subdirectories contained in that directory. Thank you for watching and don’t forget to subscribe to the SMKS Channel. In the next lesson we will look into Ownership.
References: Linux Bible 8th BibleLinux 3 - File SystemSMKS2015-01-06 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
In this video we explore the purpose of each of the high level sub directories of root. We understand the structure of the file system and what data, devices, symlinks and folders represent on it.
bin - is a standard subdirectory of the root directory in Unix-like operating systems that contains the executable (i.e., ready to run) programs that must be available in order to attain minimal functionality for the purposes of booting (i.e., starting) and repairing a system.
There is another directory known as sbin that holds only administrative commands and daemon processes.
The boot directory stores data that is used before the kernel begins executing user-mode programs. This may include redundant (back-up) master boot records, sector/system map files, the kernel and other important boot files and data that is not directly edited by hand.
dev stands for device and is the directory location of special or device files. On Linux, devices are shown as files. Some of these device files allow users to funnel information into them like they are real files. Examples being hard disks, RAM and CD-ROM.
The etc directory contains administrative configuration files. It is advised not to edit them as it could render your system unstable or in some circumstances unbootable.
The home directory contains directories assigned to each regular user with a login account. This would of course exclude the root user.
The media directory is for mounting filesystems on removable media like CD-ROM drives, USB sticks, and Zip drives.
The lib directory contains shared libraries needed by applications in bin and sbin to boot the system.
mnt is a common mount point for many devices before it was supplanted by the standard media directory.
misc - a directory sometimes used to auto mount file systems.
opt directory is available to store add on application software.
proc contains information about system resources.
root is the home directory of the root user.
The tmp (temp) directory contains temporary files used by applications.
The usr (user) directory contains the largest share of data on the system. User documentation, games, graphical files, libraries and a variety of commands and files not needed during the boot process.
The var directory contains data used by various applications. An example being a web server, this could be found at /var/www.
In this lesson we delve into what is a Class and Object is in Object Oriented Programming terms. Using real world examples of Objects we can see how they can be modeled into Computer applications and games. We understand what are attributes and methods of an Object using examples of each.
We go through step by step on the construction of a class file called Player.as, we step through the structure and syntax necessary. We learn about Strictly typed and the use of Constructors. By the end of this lesson you should understand the difference between a Class and an Object.Linux 2 - Terminal & GUISMKS2014-11-22 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
In this tutorial we will look into the boot up of Linux. The difference between Desktop and Server editions, the Graphical User interface and the system console. We understand further what a system console is, plus the terminal that emulates it.
We look at a boot process, where it detects hardware and the status of the boot procedure. We then move on to how I emulate a Linux box with the use of Virtual box and Vagrant. We look at what SSH is and it’s purpose as a Cryptographic network protocol. Then briefly touch upon a few commands available to us on the shell prompt.
Hello and welcome to a brand new course on the Linux Operating System (Re-uploaded for correctness). This lesson will explain what Linux is and how it combines with GNU. We will look at 3 different types of kernels and the differences between them. We will see the impact it has had on the 21st Century. We touch upon the idea of Open source software and the the idea of a Linux Distribution/Distro.
A book recommendation would be the Linux bible by Christopher Negus.
In this brand new course, we will be covering many aspects of the Object Oriented Programming Paradigm. Making use of the Blue Karma Point and Click Adventure game, we will see examples of why making use of this paradigm can help with organisation and maintainability in a project.
Well here it is; the last episode of the course. Really appreciate the feedback I have got from everyone on these videos. It means I will have to work on more. My next course will be on Object Oriented Programming. Something I cannot wait to start.
This episode concentrates on the policies of a file manager. Using a metaphoric example of a library.
Understanding Operating Systems by Ann and Flynn Operating Systems Design and Implementation Operating Systems Concepts
Thanks for following on with this course and good luck with all your studies.Operating Systems 4 - Device Manager Part 2SMKS2014-05-03 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
You can make donations here to help me make more of these videos.
Good source for more detailed information (No affiliation): Understanding Operating Systems by Ann McHoes and Ida M. Flynn
I hope this and the other videos help you with your studies.Operating Systems 4 - Device Manager Part 1SMKS2014-04-23 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
You can make donations here to help me make more of these videos.
Good source for more detailed information (No affiliation): Understanding Operating Systems by Ann McHoes and Ida M. Flynn
I hope this and the other videos help you with your studies.Operating Systems 3 - Process Manager Part 2SMKS2014-02-08 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
Part 2 of 2 of the Process Manager Operating Systems tutorials
In this tutorial we shall delve into the following:
Scheduling Policies Resource Hogging Locked Resources Policies First Come first serve Shortest Job Next Shortest Remaining time Pre-emptive schedulers Non-Pre-emptive schedulers Round Robin Starvation Deadlock Livelock
Good source for more detailed information on the subject (No affiliation):
Understanding Operating Systems by Ann and FlynnOperating Systems 3 - Process Manager Part 1SMKS2013-08-25 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
Part 1 of 2 of the Process Manager Operating Systems tutorials
In this tutorial we shall begin with the process manager and look at performance, speed and bandwidth of processors, clock speeds, and Cache memory. We will also look into the different states a processor can be in and look at examples of them.
Good source for more detailed information (No affiliation):
Understanding Operating Systems by Ann and Flynn http://www.amazon.co.uk/Understanding...Operating Systems 2 - Memory ManagerSMKS2013-06-18 | Suggest new or help me make more videos here: http://patreon.com/opencanvas
In this tutorial we shall begin with the memory manager and look at three old schemes of memory management. Then look at newer alternatives in Paged and Segment memory allocation.
Narrator: Sean Chiplock - http://www.peopleperhour.com/freelanc...
This new series will illustratively explain operating systems. Looking into the different managers needed to operate. This tutorial will cover what an operating system is, the types of operating systems available and how we as users interact with the operating system to carry out tasks.
Narrator: Sean Chiplock - http://www.peopleperhour.com/freelanc...