Mijn Enz.

Zo even ventileren, hebben jullie ook zoveel mijn diensten?
Ik sterf van de diensten die zich indentificeren met mij dat ik geloof ik een stevig gespleten persoonlijkheid heb.

Mijn tele2, mijn vodaphone, mijn duo, mijn cbr, mijn belastingdienst, mijn elkien (woningstichting), mijn randstad en uiteraard mijn uwv.

Mijn god,
wat een ongeloofwaardig gedoe.

And action!

It’s been a while for me to be writing again, first off it’s pre- production time again.
This time its for one of the old teammates and a few friends we’ve made along the way.

The production title i can’t give away yet but it will use a considerable amount of music and audio production.
The light department will also make a few tiny steps,  lights are an essential part of any film or photography production unit but,
I’ve never actually owned any equipment myself, mainly because of the individual and specific nature of my productions secondly because I couldn’t afford to buy it all.

This sometimes seems weird to people although it feels natural to me to rent equipment instead of buying the world on light, rigging cameras and other electrical or mechanical inventory. This time we’ll rent a few heavy-er tungsten lights for a few shots where there’ s some distance to the target and a few professional led fixtures. The cost are a minimal around 200 euros. This way allot of effort can go into taking the shot instead of “making it” in a artificial matter with either post production or incredible effort on the light sensitivity of our camera.

Hopefully we’ll be filming mid September somewhere.

Pooled Communication

Slack is fast easy transparent non-disruptive pooled

Direct, or instant messaging can annoy the living daylights out of me. Having to constantly sift through all the shitriddled message streams from work colleagues & students – all mixed in with private matters. Or being bugged during every waking hour of the day with unimportant messages from all sides. This morass of communications is not just annoying: it can be very inefficient, and at times even, very inopportune.

First & foremost, I didn’t want to accept all my students on my private Facebook account. Nor set up a secondary account for the sole purpose of managing my classroom; since I’m currently on the threshold of quitting that particular platform altogether…

Then there are the standard messaging platforms: Whatsapp, Telegram, Signal, Google Hangouts, Skype and ICQ. To my mind there is too much an emphasis on direct contact; which is something I like as well – just not in a messaging format.

In pooled communication it’s common practice not to expect a direct, or immediate response. The facility for private & direct communications is included in the platform – but really this platform is about collaboration, teamwork and development.

In an attempt to solve my problem I’ve started using Slack in a small group, as I first want to give it a good trial-run, before we attempt to roll it out department wide.

This is slack

History and founding of Slack

Slack is a team communication tool founded by Stewart Butterfield. It began as an internal tool used by Stewart’s company while developing a now defunct online game. Stewart, being one of the Co-founders of Flickr, made sure that Slack is a rock solid platform that does incredible things for team management.

First Year
2015

Second Year
2016

So, why Slack?

If you work in a team, spread accross several different locations, as many of us do; it’s likely you’ve come across problems, or struggled yourself, with clear communications. As our business’s or projects grow, we’ve found that our team communications become increasingly cluttered, and hard to keep track of, in our email inbox(es!).

Very often, we just need to send a simple message to each other, to update the others on the progress of a specific task. We’re doing this via email, Skype, and even Whatsapp – some of which are heavily reliant on support from either internal, or external, services.

And although certain information rationally needs only to be communicated to one person – we want more transparency.

This is because it helps the teams if everyone is made aware of what’s going on in all projects/classes of our school department; in order to either interject, ask a question, or for individuals to plan their own work around what was being done elsewhere. As I said, one of the main antagonisms for our team was the miriad of platforms & methods we were using to communicate. It quickly became overwhelming to keep track of email threads a mile deep, Skype conversations, text messages, and all the other places in which we were talking to each other.

1. All team communications in one place

Slack communications all occur in one place, and can be segmented by creating Channels for various topics. You can assign your users to as many (or as few) channels as you need, in order to keep topics visible to the team members you want to see any individual topic.

1
2
3
4
5
6
1

Quick Switcher for a search within contacts and channels.

2

Menu with profile, account and team specific settings.

3

Assisted search

4

Channel settings.

5

Channel details

6

The actual information shared.


This is a great way for our entire team to keep up with our company posts, and posts on the personal sites of our team members. It also ensures we all know what content is being put out publicly, and what is communicated within the team only.

 

2. Integration with services we already use

As you can see if you look closely at the Channels in the image above, we can integrate Slack with web services we use everyday.

  • GitHub – For notification and viewing the code checks & corrections from our development team.
  • HelpScout – Our email support ticket service. The entire teams sees support ticket submissions in real time.
  • Trello – Our project organization tool. We see cards created/edited/completed in our Trello portal instantly.

Click here to see the full list of available integrations.

3. All content is searchable from one search box

Have you ever searched your email inbox to find that one piece of information you needed buried deep within a thread? (at the moment our Novel client gets so worked up by search querys that it just stops looking altogether..!)

Slack makes it dead simple to find that link which someone posted 3 weeks ago, that you just now want to go have a look at. Not only is the search super fast and friendly, but it’s also filterable.

Imagine this scenario… You remember you were chatting with Bob one day and he posted a link to a really great resource on what you need to accomplish with a certain task, but you can’t quite remember what the link or website was named.

Use the Slack search filter options to narrow your search to conversations only with Bob, only in a certain channel, or any of several other filters.

4. File sharing

We’re in the WordPress plugin business and we share a lot of files. Many times this comes in the form of beta versions of our new plugin releases.

Slack makes it simple to share these files quickly with our entire team and it also has Dropbox integration for more in depth file access.

Sharing Software Versions in Slack

File sharing is not just for software either. It’s also great for getting a little more personal with the team.

Here are a few of the images I shared and received recently from students and co-workers…

5. Code snippets

Teaching a class programming takes a lot of communication on a daily basis. Not only that, but supporting and implementing the products made on the various platforms where our students have their products, or services, installed sometimes takes a fair amount of communication.

Being able to share and test code snippets across our team in an instant is a great feature of Slack that shouldn’t go unmentioned. This alone has increased our productivity by leaps and bounds.

Not only that, but any code snippet we create stays within our Slack portal, and is available to us at any time in the future.

Slack Code Snippet Sharing

Slack Code Snippet Sharing

6. One to one and private groups

Transparency in team communications is certainly a great option, but there are times when you need to communicate something privately between the members of your team.

Perhaps it’s payroll related, or some other personal situation the whole team doesn’t need to be in on.

Just like any other chat client, Slack makes it simple to exchange messages privately between two people.

7. Accessible anywhere

Slack has mobile apps available too. Personally, I use the android app on my phone and I couldn’t be happier with it’s layout and functionality.

I often have to run errands during the day. Being able to keep up with my work communications has really helped to round out my day, and keep me in the loop on the tasks I need to follow up on after the kids go to bed.

7. How much does slack cost?

Slack offers four pricing options, and up until the time of this writing, we’ve been on the free plan (also known as the Lite plan).

The first paid option starts at just $8 monthly per user, and if you fall in love with Slack like we have, it’s a drop in the ocean for the time/cost savings we’re already experiencing.

To learn more about Slack and see all the features, go here right now.

Bonus!

If you sign up for the free version of Slack using the link above, you’ll get a $100 credit if you ever decide to upgrade to a paid plan.

Slack continues to creep into offices and organizations worldwide, bringing a new and intuitive approach to the old group-chat model. If you’ve been signed up for the service at your workplace, then here are ten ways to wow your fellow workers with your Slack skills.

A few quick slack tips

1. Put up a ‘Do Not Disturb’ sign

It’s easy to get overwhelmed with notifications and alerts on Slack, which may be why the developers recently added a Do Not Disturb mode. When it’s activated, you won’t get any sounds or notifications on any of your devices, and your co-workers will see a little sleeping symbol at the side of your name.

10 Tips To Make You a Slack Wizard

Click the bell icon (top left) to choose a time duration, or click on Do Not Disturb schedule and you can have it turn on automatically—very useful if you’re in a different time zone to everyone else. You can also activate Do Not Disturb by typing /dnd followed by a time period into the Slack chat field.


2. Get reminders from slackbot

Slackbot knows all kinds of tricks and can be as useful as Siri or Google Now when leaving you reminders. Head into your direct message conversation with Slackbot, type /remind into the chat field and then leave some reminder text and a time. You’ll see a confirmation message on screen.

You can also leave reminders for other people and specific channels (just type /remind on its own to see various ways in which you can leave messages). If you want to see all of the reminders that are currently active, type /remind list into the chat field (you can delete them from here too).


3. Make use of slack’s advanced search operators

As with your regular search engine of choice, you can use operators to narrow down your searches in Slack (very helpful for those busier channels). For example, type has:star inside the search box to look for all starred messages or try from:username to look for messages from a certain person.

10 Tips To Make You a Slack Wizard

To see all of the operators available to you, type + in the search box: you can find messages in or to a particular channel, restrict your search to a particular range of dates, and look for messages with links in them. Related and recent searches pop up underneath as you continue typing.


4. Keyboard shortcuts

From Photoshop to Gmail, keyboard shortcuts can make a big difference to your productivity levels, and there are plenty to play around with in Slack too. For example, if you just typed something and noticed a mistake, press the Up arrow to get back to it. There’s a full list on the Slack support site.

The quick switcher shortcut is another useful one: press Ctrl+K on Windows or Cmd+K on a Mac, then start typing to jump to specific channels or message threads. You can use the Esc key as an easy way of marking all the messages in the current channel, or conversation, as read.


5. Add your own emoji

Everyone loves emoji and you can add your own to the conversation by opening up the main Slack menu on the web and choosing Customize (please note: the options you see here will vary depending on how your team’s account has been set up). You can add customized loading messages from here too.

10 Tips To Make You a Slack Wizard

All you need to set up a new emoji symbol is a picture of said emoji and a shortcut name for it—anything you create will be available to everyone on your team and will be added to the custom tab of the emoji menu (click the smiley face to the right of the message field to see all the symbols).


6. Tidy up the feed

Image and link previews are part of the appeal of Slack, but if you’ve got particularly GIF-happy colleagues or there are a lot of links to wade through then your screen can get very busy very quickly. Type /collapse to hide all image previews in the current channel and /expand to bring them back.

There are a host of helpful commands that begin with the slash symbol—just type / in the message field to see them all pop up. Some of them may have been added by the people who set up your Slack channel, and any third-party plug-ins and add-ons will have similar commands of their own.


7. Format the text of your messages

In case you need help getting your point across, Slack supports the usual text formatting tricks found in many messaging apps: put asterisks around words you want to make bold, and underscores around anything you want to appear in italics. The tilde symbol (~) either side adds a strikethrough effect.

10 Tips To Make You a Slack Wizard

If you need to create a message that goes on for several lines, then use Shift+Enter to add new lines without posting the message. It’s also possible to create blockquotes by preceding text with an angled bracket (>)—to keep the blockquote across several lines, use three angled brackets (>>>).


8. Keep your place in a channel

You can keep your place in a channel with an Alt+click (or Option+click) on a particular message—this marks it (and all subsequent messages) as unread, so you can easily jump back to it later. A long press on a particular message brings up the same option (and several others) in the Slack mobile apps.

To change the way that Slack automatically marks messages as read when you jump back into a particular team or channel, open up Preferences from the main Slack menu then choose Read State Tracking. By default, Slack marks everything in a channel as read once you open it up.


9. Change the look of Slack

Slack has a distinctive default color scheme, but you don’t have to settle for that look if you don’t want to. From the main Slack menu on the web, choose Preferences and then open up the Sidebar Theme menu—there are eight preset ones to choose from, or you can set the colors yourself.

10 Tips To Make You a Slack Wizard

You won’t suddenly change the color scheme for everyone in your company—only you will see the new look—and each team that you’re a member of can have its own appearance settings, which can make life easier if you’re jumping around a lot between different Slack teams in one browser.


10. Link to particular messages

Right-click on a time stamp, click on the options menu to the right, or (on mobile) long press to find the specific link for a specific message—you can bookmark this or drop it back into the channel, for example, enabling you to quickly remind your co-workers exactly what they’ve said in the past.

Open up said link in a new browser window and you’ll get a snapshot of the relevant channel at the time of the message, together with more information about the channel itself. There’s an option to browse the channel by date too, if the team admin has made the relevant channel archives accessible.

 

Text Edited by Giles Wright in the UK, on 25th July 2016…

License confusion

From Open Source to Freeware & Scareware: a what’s what..!


Back in the 90’s we used to be comfortable downloading most, if not all software, from sites such as download.cnet.com and others that were commonly accepted to be reliable websites. But over the years the landscape has changed a lot. Not that the sites have changed much. Download.cnet.com is still up and still distributes a lot; but rather my taste for software has changed, as have the flavours that we can get our desired software in.

In the hedonism of the 90’s shareware was used as a promotional tool to distribute a restricted version of something. In my efforts to find affordable software since I’ve tried a lot of variations of trials, demos, freeware, shareware and opensource software. But it’s a jungle out there with a lot of outdated platforms who have inserted their advertisements and spyware into the official software & its installers.

Now in 2016 I’ve given up on doggy websites, small time and unsupported software.
I’ve moved towards opensource software combined with (old and bought) proprietary software combined with a few license subscriptions (The Foundry & Adobe).

Over the years I’ve heard a lot of inconsistent opinion within the tech community in reference to the differences between said opensource licenses, when compared to free or shareware – but there are significant differences.

A little about the differences…

Proprietary Software Licenses.


The most familiar way of acquiring your software, by purchasing the licensed software on a physical medium like an optical disk or a usb-drive. Most games and software are available this way, although a lot of the more professional software has moved to a subscription model as explained in SAAS.

Software As A Service.


SAAS is a license in the form of a subscription, with which the software is usually available and fully functional for a fixed period. A single project/production run/software edition/time period, all being possible variables. More often than not, time is the over-riding variable, with availability generally ranging from a single month, to a year, or even a lifetime (World of Warcraft/Rift).

One notable advantage of the SAAS licence is that usually during the period of paid subscription, the software is supported, maintained and updated by the provider at no extra cost. This can go part way to explain why much highly technical and professional level software has gravitated towards this kind of licence.

Ad-Ware.


This is a form of software that gives you intentional advertisements that may, or may not be for the software itself, and which are usually promoting affiliated software or services. This type of income generation is also a very popular variation in SAAS. You pay only for the removal of advertisements, not for any functionality in the software itself.

Some of the more malignant software of this type even goes as far as to install complete advertising engines that are bigger than the original software they “complement”! These advertising engines are not even focused on the associated software – and more worryingly can often prove very difficult to thoroughly cleanse from any affected machine. Particularly for those with young children around, such software can cause significant headaches.

Cripple-Ware (or Sucker-Ware as I prefer to call it..)


This software option gives you the basics but removes any production level tools rendering it utterly useless in free mode. I’m not talking about for instance a 4K export option instead of HD or 720 like Lightwave video editor delivers but more in a sense of a virus scanner that won’t actually remove something unless the paid subscription is bought or in instance of video software, something that wouldn’t be able to export at all.

It is also not uncommon for this flavour to be combined with some of the worst attributes of Ad-Ware – so perhaps the title of this section could even be: Sucker-Bware..! Some of the worst offenders in this regard are the so-called registry cleaners and software designed to “fix & speed-up” your Windows machine. It wouldn’t be so bad, and I might have avoided making the point altogether: if it wasn’t for the fact that much of the software just mentioned is also ultimately found to be trite at its job – often creating bigger problems than were originally to be found on the machine in question…

Nag-Ware


Every time you launch this software it will show you a splash screen advertising a full version and halting the start-up processes for a few seconds of mandatory waiting time, designed to focus the user on their carefully crafted advert.

Demo-Ware


This software is generally free of charge, not fully featured, and can be found in most software categories.

Usually in the form of a restricted version that is unable to do some of the more demanding functions, or in a trial format that locks down after a couple of weeks, or a fixed number of uses.

Trial-Ware


Software that is in trial is supposed to lock down after a fixed number of uses or a certain period of time. This is a common practice for SAAS to use: by giving a month of free subscription to a user to convince him/her of the practicality of the application and motivate them towards a paid subscription.

Donation-Ware


A completely free service, or application that solely survives on donations. This model can be seen in use with a lot of popular mods and plugins for applications. It is less seen in regular corporate software.

A very familiar form of business model, as commonly used to finance services such as Wikipedia, who ask their users for a voluntary contribution from time to time.

Freemium


A product or service delivered functional, but stifled up to a point that though still of use, much of the more unique &/or useful functionality is little more than a technical advert for the fully paid-up version. A lot of applications also either restrict the amount of users registered to the service, or other non-essential but very useful functionality to the software or service. Good examples of this license format are Lightwave, Trello and cCleaner.

Personal Learning Edition


A version of the software that is only for educational purposes and doesn’t have the ability to exchange its saves to a full version. Conversely, full version saves are able to be opened in a PLE.

Non-Commercial license.


Similar to a Personal Learning Edition. Only differing in the way it handles saves between the non-commercial version and a full licensed version.

OpenSource


OSS is software where its source code isn’t locked away, but made available with a license in which the copyright holder provides the full rights to study, alter, and distribute the software/code to anyone, and for any purpose.

This software takes another approach to business by stating that only expertise and knowledge should be paid and not the outcome/result of that knowledge. We’ve paid for the code’s development, so the coder has been paid for the development of the software, and it should not be necessary to acquire other means of income for the evolution of the code/program/app.

Another way to look at this: if the coder of a particular software has been paid a professional/satisfactory wage for their time spent working on the code in question (often the case in an educational environment), then it may not/should not be necessary to acquire other means of income for the development of the code. In some ways it could be characterised as a royalty-free arrangement. Though possibly not immediately obvious, there are significant advantages for the coder. If their work is good, it gets spread with much greater rapidity, and to much greater acclaim. Hence a common stipulation in this license format, is that the coder(s) be acknowledged in some way beside their work, wherever it may be used.

Footnote: if anyone questions what I have just written above – just stop for a moment and think about the music business, the Internet, and your own music collection both digital & physical..!!

 

Edited by Giles Wright in the UK, on 24th March 2016…

Javascript

A few weeks ago I’ve asked a class of first year students what they would like to learn.
Screenshot
After short deliberation they decided for JavaScript.

Now I haven’t got the spare time during their regular program to fit it in so I’ve taken the liberty to place it all here for those with extra time on their hands or a typical boring day.

So I’ve explained globally what JavaScript is and what it can do and how it behaves. The presentation slides are here for review.

Lets start with a set of websites that can be of use.
First off some educational platforms listed from dry to wet, boring to fun.

And since we’ve had only boys so far in our programming classes I’m taking the unprofessional step to have a little fun with this last site.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <script src="jstut.js"></script>

    <style type="text/css">
      body {font-size: 1.6em;}
      .hidden {display:none;}
      .show {display:inline !important;}
      button {
        border: 2px solid black; background: #E5E4E2;
        font-size: .5em; font-weight: bold; color: black;
        padding: .8em 2em;
        margin-top: .4em;
      }
    </style>

  </head>
  <body>
  <p id="sayHello"></p>
  <script>

  // You create variables that store values with var
  // Prompt opens a popup that requests info
  var yourName = prompt("What is your name?");

  // If performs different actions depending on conditions
  if(yourName != null){

    // Set text in an HTML element with the id sayHello
    // You concatenate (combine) strings with +
    document.getElementById("sayHello").innerHTML = "Hello " + yourName;
  } else {

    // Alert opens a popup that contains a message
    alert("Please Enter Your Name Next Time");
  }

// ---------- VARIABLES ----------
// variable names can't start with a number, contain spaces, but can
// contain letters, numbers, underscores or $ (Are case sensitive)
var myName = "Derek";
var myAge = 40;

// Variables don't have a defined type, which can cause problems
myName = 100;

// ---------- MATH ----------
// document.write outputs data to the browser
document.write("5 + 4 = ", 5 + 4, "<br/>");

// Using + instead of , will treat everything as a string unless you use ()
document.write("5 + 4 = " + (5 + 4) + "<br/>");

document.write("5 - 4 = ", 5 - 4, "<br/>");
document.write("5 * 4 = ", 5 * 4, "<br/>");
document.write("5 / 4 = ", 5 / 4, "<br/>");

// Modulus remainder of a division
document.write("5 % 4 = ", 5 % 4, "<br/>");

var maxNum = Number.MAX_VALUE;

document.write("Max Num = ", maxNum, "<br/>");
document.write("Min Num = ", Number.MIN_VALUE, "<br/>");

// Numbers have 16 digits of precision
precisionTest = 0.1000000000000001;
document.write(precisionTest + 0.1000000000000001, "<br/>");

// Round number to 2 decimal places
var balance = 1563.87;
document.write("Monthly payment : ", (balance / 12).toFixed(2), "<br />");

var randNum = 5;

// Shortcut for adding 1
document.write("randNum++ = ", randNum++, "<br/>");
document.write("++randNum = ", ++randNum, "<br/>");

// The same exists for -
document.write("randNum-- = ", randNum--, "<br/>");
document.write("--randNum = ", --randNum, "<br/>");

// Perform a calculation on a value and assign the result
document.write("randNum += 5 = ", randNum += 5, "<br/>");
document.write("randNum -= 5 = ", randNum -= 5, "<br/>");
document.write("randNum *= 5 = ", randNum *= 5, "<br/>");
document.write("randNum /= 5 = ", randNum /= 5, "<br/>");

// Order of operations
document.write("3 + 2 * 5 = ", 3 + 2 * 5, "<br/>");
document.write("(3 + 2) * 5 = ", (3 + 2) * 5, "<br/>");

// Math properties and methods
document.write("Math.E = ", Math.E, "<br/>");
document.write("Math.PI = ", Math.PI, "<br/>");

document.write("Math.abs(-8) = ", Math.abs(-8), "<br/>");
document.write("Math.cbrt(1000) = ", Math.cbrt(1000), "<br/>");
document.write("Math.ceil(6.45) = ", Math.ceil(6.45), "<br/>");
document.write("Math.floor(6.45) = ", Math.floor(6.45), "<br/>");
document.write("Math.round(6.45) = ", Math.round(6.45), "<br/>");
document.write("Math.log(10) = ", Math.log(10), "<br/>"); // Natural log
document.write("Math.log10(10) = ", Math.log10(10), "<br/>"); // Base 10 log
document.write("Math.max(10,5) = ", Math.max(10,5), "<br/>");
document.write("Math.min(10,5) = ", Math.min(10,5), "<br/>");
document.write("Math.pow(4,2) = ", Math.pow(4,2), "<br/>");
document.write("Math.sqrt(1000) = ", Math.sqrt(1000), "<br/>");

document.write("Random # (1-10) = ", Math.floor((Math.random() * 10) + 1), "<br/>");

// Convert strings to numbers
document.write("Converted String : ", Number("3.14"), "<br />");

document.write("Converted Int : ", parseInt("5"), "<br />");
document.write("Converted Float : ", parseFloat("5.555"), "<br />");

// ---------- STRINGS ----------
var randStr = "A long " + "string that " + "goes on and on";

// String length
document.write("String Length : ", randStr.length + "<br/>");

document.write("Index for \"goes\" : ", randStr.indexOf("goes"), "<br/>");

// Return the value using a start and end index
document.write(randStr.slice(19, 23) + "<br/>");

// Return everything after the start index
document.write(randStr.slice(19) + "<br/>");

// Return the value using the start index and length
document.write(randStr.substr(19, 4) + "<br/>");

// Replace a string
document.write(randStr.replace("and on", "forever") + "<br/>");

// Get character at an index
document.write("At Index 2 : ", randStr.charAt(2) + "<br/>");

// Split a string into an array
var randStrArray = randStr.split(" ");

// Trim white space
randStr = randStr.trim();

// Convert to uppercase
document.write(randStr.toUpperCase() + "<br/>");

// Convert to lowercase
document.write(randStr.toLowerCase() + "<br/>");

// Styling with JS
var strToStyle = "Random String";

document.write("Big : ", strToStyle.big(), "<br />");
document.write("Bold : ", strToStyle.bold(), "<br />");
document.write("Font Color : ", strToStyle.fontcolor("blue"), "<br />");
document.write("Font Size : ", strToStyle.fontsize("8em"), "<br />");
document.write("Italics : ", strToStyle.italics(), "<br />");
document.write("Google : ", strToStyle.link("http://google.com"), "<br />");
document.write("Small : ", strToStyle.small(), "<br />");
document.write("Strike : ", strToStyle.strike(), "<br />");
document.write("Sub : ", strToStyle.sub(), "<br />");
document.write("Sup : ", strToStyle.sup(), "<br />");


// ---------- CONDITIONALS ----------
// Relational Operators : == != > < >= <=
// === : Equal value and type
// Logical Operators : && \\ !

var age = 8;

if ((age >= 5) && (age <= 6)){
  document.write("Go to Kindergarten<br />");
} else if (age > 18) {
  document.write("Go to College<br />");
} else {
  document.write("Go to Grade ", age - 5, "<br />");
}

document.write("true || false = ", true || false, "<br />");

document.write("!true = ", ! true, "<br />");

document.write("\"5\" == 5 = ", ("5" == 5), "<br />");

document.write("\"5\" === 5 = ", ("5" === 5), "<br />");

// Switch is used to match a limited number of options
switch(age) {
  case 5 :
  case 6 :
    document.write("Go to Kindergarten<br />");
    break;

  case 7 :
    document.write("Go to 1st Grade<br />");
    break;

  default :
    document.write("Subtract 5 from your age<br />");
}

// Ternary Operator assigns a value based on a condition
// (condition) ? iftrue : ifFalse
var canIVote = (age >= 18) ? true : false;

document.write("Can I Vote : ", canIVote, "<br />");

// ---------- LOOPING ----------

// while loops as long as a condition is true
var i = 1;
while (i <= 10){
  document.write(i, ", ");
  i++;
}
document.write("<br />");

// do while is used when you must go through the loop at least once
do{
  var guess = prompt("Guess a number between 1 and 20");
}while(guess != 15)

alert("You guessed it! 15 was the number");

// for is a self contained looping structure
for(j = 0; j <= 20; j++){

  // If j is divisible by 2 then skip back to the top of the loop
  if((j % 2) == 0){
    continue;
  }

  // If j is equal to 15 break completely out of the loop
  if(j == 15){
    break;
  }
  document.write(j, ", ");
}
document.write("<br />");

var customer = {name : "Bob Thomas", address : "123 Main", balance : 50.50};

// for in cycles through an enumerable properties of an object
for(k in customer){
  document.write(customer[k], "<br />");
}

// ---------- ARRAYS ----------
// Arrays have variable sizes and can contain multiple types in JS
var tomSmith = ["Tom Smith", "123 Main", 120.50];

// Access first array item
document.write("1st State : ", tomSmith[0], "<br />");

// Add an item
tomSmith[3] = "tsmith@aol.com";

// Overwrite index 2 and fit everything else after index 2 without
// overwriting (Put 0 for second parameter to not overwrite)
tomSmith.splice(2, 1, "Pittsburgh", "PA");

// Delete the 4th index item
tomSmith.splice(4,1);

// Convert an array into a string (Also use toString())
document.write("Array : ", tomSmith.valueOf(), "<br />");

// Convert an array into a string with separator
document.write("Array : ", tomSmith.join(", "), "<br />");

// Delete an index
delete tomSmith[3];

// Sort an array (reverse() for reverse sort)
// Works for sorting strings
tomSmith.sort();

// Sort numbers
var numbers = [4,3,9,1,20,43];

// Descending sort return y - x
numbers.sort(function(x,y){ return x - y });
document.write("Num Array : ", numbers.toString(), "<br />");

// Combine arrays
var combinedArray = numbers.concat(tomSmith);

// Remove the last item
tomSmith.pop();

// Add items to the end
tomSmith.push("555-1212", "US");

// Deletes the first item
tomSmith.shift();

// Adds item to the first index
tomSmith.unshift("Tom Smith");

for (var i = 0; i < tomSmith.length; i++) {
  document.write(tomSmith[i], "<br />");
}

// ---------- FUNCTIONS ----------
// Functions provide code reuse and eliminate repetitive code

// Define a function that checks if a value is in an array
function inArray(arrayToCheck, value){
  for(i = 0; i < arrayToCheck.length; i++){
    if(arrayToCheck[i] === value){
      return true;
    }
  }
  return false;
}

var randArray = [1,2,3,4,5];

document.write("In Array : ", inArray(randArray, 4), "<br />");

// Local variables defined in functions can't be accessed outside of
// the function

function times2(num){
  var var2 = 2;
  return num * var2;
}

// Causes Error : document.write("Val of var2 : ", var2, "<br />");

// Pass a function as a parameter
function times3(num){
  return num * 3;
}

function multiply(func, num){
  return func(num);
}

document.write("3 * 15 = ", multiply(times3, 15), "<br />");

// Define a function expression
// We can assign functions to variables, store them in arrays,
// pass them into other functions and return them from functions
var triple = function(num){
  return num * 3;
};

document.write("3 * 45 = ", multiply(triple, 45), "<br />");

// Receive variable number of arguments
function getSum(){
  var sum = 0;
  for(i = 0; i < arguments.length; i++){
    sum += arguments[i];
  }
  return sum;
}

document.write("Sum : ", getSum(1,2,3,4,5), "<br />");

// Return a variable number of values
function times2(theArray){

  var newArray = [];
  for(i = 0; i < theArray.length; i++){
    newArray.push(theArray[i] * 2);
  }
  return newArray;
}

document.write("Array Doubled : ", times2([1,2,3,4,5]).toString(), "<br />");

// Recursive Function
function factorial(num){
  if(num <= 1){
    return 1;
  } else {
    return num * factorial(num - 1);
  }
}

document.write("Factorial of 4 : ", factorial(4), "<br />");

// 1st: num = 4 * factorial(3) = 4 * 6 = 24
// 2nd: num = 3 * factorial(2) = 3 * 2 = 6
// 3rd: num = 2 * factorial(1) = 2 * 1 = 2


// ---------- EVENT HANDLING ----------
function openAlert(mess){
  alert(mess);
}


// ---------- DATE ----------
// Get a Date object
var curDate = new Date();

document.write("Date : ", curDate.getDate(), "<br />");
document.write("Month : ", curDate.getMonth(), "<br />");
document.write("Day : ", curDate.getDay(), "<br />");
document.write("Year : ", curDate.getFullYear(), "<br />");
document.write("Time : ", curDate.getHours(), ":", curDate.getMinutes(),
  ":", curDate.getSeconds(), ":", curDate.getMilliseconds(), "<br />");

// Create a Date object for my birthday
var myBD = new Date("December 21, 2015");

var msForBD = myBD.getTime();
var timeNow = curDate.getTime();
var tilMyBD = msForBD - timeNow;

document.write("Days til Birthday : ", tilMyBD / (1000 * 60 * 60 * 24), "<br />");

</script>

<!-- ---------- CHANGING ELEMENTS & EVENT HANDLING ---------- -->
<!-- All the events can be found here http://www.w3schools.com/jsref/dom_obj_event.asp -->

<!-- Open alert on click -->
<a href="JavaScript:void(0)" onClick="alert('Hello');">Say Hello</a><br />

<!-- Call a function on click -->
<a href="JavaScript:void(0)" onClick="openAlert('Hi how are you');">Say Something</a><br />

<!-- Change text color on mouse rollover and roll out-->
<a href="JavaScript:void(0)" onmouseover="this.style.color='red';"
onmouseout="this.style.color='blue';"
ondblclick="this.text='You Double Clicked Me'"
onmousedown="this.text='Don\'t Press So hard'"
onmouseup="this.text='Thank You'">Make me Red</a><br />

<!-- Get value in an input element and open alert on change -->
<input type="text" id="randInput"
onChange="var dataEntered=document.getElementById('randInput').value; alert('User Typed ' + dataEntered);"><br /><br />

<!-- When a user clicks a key provide info on the key clicked -->
<form action="#" id="sampForm">
<input id='charInput' type="text">
<p id="keyData">Key Data Here</p>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form><br /><br />

<img src="ntt-logo.png" id="logo">
<button id="logoButton">Get Logo</button><br />
<input id='mouseInput' type="text" size="30"><br />

Mouse X: <input type="text" id="mouseX"><br />
Mouse Y: <input type="text" id="mouseY"><br />

<button id="clearInputs">Clear Inputs</button><br />

<script>

function getChar(event) {

  // event.which returns the key or mouse button clicked
  if (event.which == null) {

    // Return the char if not a special character
    return String.fromCharCode(event.keyCode); // IE
  } else if (event.which!=0 && event.charCode!=0) {
    return String.fromCharCode(event.which);   // Other Browsers
  } else {
    return null; // Special Key Clicked
  }
}

document.getElementById('charInput').onkeypress = function(event) {
  var char = getChar(event || window.event)
  if (!char) return false; // Special Key Clicked

  document.getElementById('keyData').innerHTML = char + " was clicked";
  return true;
}

// Change text when the input gains focus
document.getElementById('charInput').onfocus = function(event) {
  document.getElementById('keyData').innerHTML = "Input Gained Focus";
}

// Change text when the input loses focus
document.getElementById('charInput').onblur = function(event) {
  document.getElementById('keyData').innerHTML = "Input Lost Focus";
}

// Change text when text is selected
document.getElementById('charInput').onselect = function(event) {
  document.getElementById('keyData').innerHTML = "Text Selected";
}

// Add a listener that triggers a function on browser resize
window.addEventListener("resize", browserResized);

function browserResized() {
  document.getElementById('keyData').innerHTML = "I've been resized";
}

// Make image invisible on click
document.getElementById('logo').onclick = function(event) {

  // Change the class for the image
  document.getElementById('logo').className = "hidden";

  // Change the input element value
  document.getElementById('mouseInput').value = "Clicked on image with button " + event.button;
}

// Make image visible on click
document.getElementById('logoButton').onclick = function(event) {
  document.getElementById('logo').className = "show";
}

// Change image src on mouseover
document.getElementById('logo').onmouseover = function(event) {
  document.getElementById('logo').src = "ntt-logo-horz.png";
  document.getElementById('mouseInput').value = "Mouse Over image";
}

// Change image src back on mouseout
document.getElementById('logo').onmouseout = function(event) {
  document.getElementById('logo').src = "ntt-logo.png";
  document.getElementById('mouseInput').value = "Mouse Left image";
}

// Get mouse x y coordinates
document.body.onmousemove = function(e) {
    e = e || window.event;

    // Get pageX, pageY : Mouse position relative to the html doc
    var pageX = e.pageX;
    var pageY = e.pageY;
    if (pageX === undefined) {

        // clientX, clientY : Mouse position relative to the browsers viewport
        // scrollLeft, scrollTop : Pixels an element is scrolled left or
        // from the top
        pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

    document.getElementById('mouseX').value = pageX;
    document.getElementById('mouseY').value = pageY;
};

// Clear all input elements
document.getElementById('clearInputs').onclick = function(event) {
  var inputElements = document.getElementsByTagName('input');

  for (var i = 0; i < inputElements.length; i++) {
  if (inputElements[i].type == "text") {
    inputElements[i].value = "";
  }
}
}

</script>

<!-- ---------- ELEMENT STYLING ---------- -->
<!-- See all of them here http://www.w3schools.com/jsref/dom_obj_style.asp -->

<div id="sampDiv">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin eget turpis eget quam luctus malesuada ut ac nulla. Suspendisse fermentum magna neque, a auctor felis pretium eget. Fusce ornare feugiat magna, ut faucibus sapien congue ut. Nunc nec fringilla ex, nec varius nisl. Ut eget laoreet nisi. Aenean quis venenatis mauris, at volutpat ante. Donec sollicitudin lacinia ornare. In quis accumsan ligula, id egestas enim.
</div>

<button id="chgBkColor">Background Color</button>
<button id="chgBkImg">Background Image</button>
<button id="chgBorderStyle">Border Style</button>
<button id="chgBorderWidth">Border Width</button>
<button id="chgBorderColor">Border Color</button>

<script type="text/javascript">

// Change background color
document.getElementById('chgBkColor').onclick = function(event) {
  document.getElementById('sampDiv').style.backgroundColor = "#EFDECD";
}

// Change background image
document.getElementById('chgBkImg').onclick = function(event) {
  document.getElementById('sampDiv').style.backgroundImage = "url('repeatBkgrnd.png')";
}

// Change border style
document.getElementById('chgBorderStyle').onclick = function(event) {
  document.getElementById('sampDiv').style.borderStyle = "solid";
}

// Change border width
document.getElementById('chgBorderWidth').onclick = function(event) {
  document.getElementById('sampDiv').style.borderWidth = "thick";
}

// Change border color
document.getElementById('chgBorderColor').onclick = function(event) {
  document.getElementById('sampDiv').style.borderColor = "blue";
}
</script>

<!-- ---------- MANIPULATING THE DOM ---------- -->

<div id="sampDiv2"><p>Lorem ipsum dolor sit amet, <em>consectetur adipiscing</em> elit. Proin eget turpis eget quam luctus malesuada ut ac nulla. Suspendisse fermentum magna neque, a auctor felis pretium eget. Fusce ornare feugiat magna, ut faucibus sapien congue ut. Nunc nec fringilla ex, nec varius nisl. Ut eget laoreet nisi. Aenean quis venenatis mauris, at volutpat ante. Donec sollicitudin lacinia ornare. In quis accumsan ligula, id egestas enim.</p><p>Lorem ipsum dolor sit amet, <b>consectetur adipiscing</b> elit. Proin eget turpis eget quam luctus malesuada ut ac nulla. Suspendisse fermentum magna neque, a auctor felis pretium eget. <em>Fusce ornare</em> feugiat magna, ut faucibus sapien congue ut. <b>Nunc nec fringilla</b> ex, nec varius nisl.</p></div>

<img src="ntt-logo.png" id="logo2" alt="NTT Logo" height="180" width="180"><br />

<button id="goToGoogle">Go to Google</button><br />

<button id="forwardPage">Forward Page</button><br />

<button id="backPage">Back Page</button><br />

<button id="reload">Reload Page</button><br />

<script type="text/javascript">

// Get current web page info
document.write("Current URL : ", window.location.href, "<br />");
document.write("Current Host : ", window.location.hostname, "<br />");
document.write("Current Path : ", window.location.pathname, "<br />");

// Change site on button click
document.getElementById('goToGoogle').onclick = function(event) {
  window.location.href = "http://google.com";
  // OR
  // window.location.assign("http://google.com");
}

// Go forward a page on click
document.getElementById('forwardPage').onclick = function(event) {
  history.forward();
}

// Go back a page on click
document.getElementById('forwardPage').onclick = function(event) {
  history.back();
}

// Use history.go(-2) or history.go(2) to jump multiple pages

// Reload page on button click
document.getElementById('reload').onclick = function(event) {
  window.location.reload(true);
}

// You can get all ps and then target them like an array
var pElements = document.getElementsByTagName('p');
pElements[3].style.backgroundColor = "#EFDECD";

// Target the html
document.childNodes[1].style.backgroundColor = "#FAEBD7";

// Change the color of the 1st child in sampDiv2
var sampDiv2 = document.getElementById('sampDiv2');
sampDiv2.childNodes[0].style.backgroundColor = "#F0FFFF";

// Style the 1st child of sampDivs 1st child
sampDiv2.childNodes[0].childNodes[1].style.backgroundColor = "#BFAFB2";

// JavaScript can get confused by text nodes when targeting elements
// Text nodes are whitespace, which nodeType will identify with a 3
// while elements as a 1
// You can eliminate text nodes by deleting whitespace or by using a
// minimizer (lastChild and firstChild may not work)
document.write("Node Type : ", sampDiv2.childNodes[0].childNodes[0].nodeType, "<br />");

document.write("Node Name : ", sampDiv2.childNodes[0].childNodes[0].nodeName, "<br />");

sampDiv2.childNodes[1].childNodes[3].style.backgroundColor = "#BFAFB2";

// Changing element attributes
var nttLogo2 = document.getElementById('logo2');

// Check for attributes
document.write("Logo has alt : ", nttLogo2.hasAttribute("alt"), "<br />");

// Change attribute
nttLogo2.setAttribute("alt", "NTT Logo 2");

// Get attribute
document.write("Logo alt Value : ", nttLogo2.getAttribute("alt"), "<br />");

// Get all attributes and print them
var attribList = document.getElementById('logo2').attributes;

for(i = 0; i < attribList.length; i++){
  document.write("Attribute ", i, " : ", attribList[i].nodeName, " : ", attribList[i].nodeValue, "<br />");
}

// Add a p element after setting an attribute and text
var paragraph3 = document.createElement("p");

paragraph3.setAttribute("id", "paragraph3");

paragraph3.innerHTML = "Proin eget turpis eget quam luctus malesuada ut ac nulla.";

sampDiv2.appendChild(paragraph3);

// Insert the element before the 1st child
sampDiv2.insertBefore(paragraph3, sampDiv2.childNodes[0]);

</script>

<!-- ---------- OO JAVASCRIPT ---------- -->

<script type="text/javascript">

// Create a customer object by defining the attributes of John Smith
// The variable is a reference to the object in memory
var cust1 = {
  name: "John Smith",
  street: "123 Main",
  city: "Pittsburgh",
  state: "PA",
  email: "jsmith@aol.com",
  balance: 120.50,
  payDownBal: function(amtPaid){
    this.balance -= amtPaid;
  },
  addToBal: function(amtCharged){
    this.balance += amtCharged;
  }
};

// Retrieve the value for the object
document.write("Customer Name : ", cust1.name, "<br />");

// Change the value for the object
cust1.street = "215 Main St";
document.write("Customer Address : ", cust1.street, "<br />");

// Add a property to cust1
cust1.country = "US";
document.write("Customer Country : ", cust1.country, "<br />");

// Delete a property
delete cust1.country;

// Cycle through all the properties for the object
for (var prop in cust1) {
    if (cust1.hasOwnProperty(prop)) {
        document.write(prop, "<br />");
    }
}

// Check if a property is in an object
document.write("name in cust1 : ", "name" in cust1, "<br />");

// Interact with an object using a function
function getInfo(cust){
  return cust1.name + " lives at " + cust1.street + " in " + cust1.city + " " + cust1.state + " email : " + cust1.email + " and has a balance of $" + cust1.balance;
}

document.write(getInfo(cust1), "<br />");

// Call object methods
cust1.payDownBal(20.50);
cust1.addToBal(10.00);

document.write(getInfo(cust1), "<br />");

// Create an object constructor
function Customer(name, street, city, state, email, balance){
  this.name = name;
  this.street = street;
  this.city = city;
  this.state = state;
  this.email = email;
  this.balance = balance;

  this.payDownBal = function(amtPaid){
    this.balance -= amtPaid;
  };
  this.addToBal = function(amtCharged){
    this.balance += amtCharged;
  };
}

var cust2 = new Customer("Sally Smith", "234 Main", "Pittsburgh", "PA", "ssmith@aol.com", 0.00);

cust2.addToBal(15.50);

// Define a shared prototype property for all objects
Customer.prototype.isCreditAvail = true;

// We define prototype methods that are shared by every object created
Customer.prototype.toString = function(){
    return this.name + " lives at " + this.street + " in " + this.city + " " + this.state + " email : " + this.email + " and has a balance of $" + this.balance.toFixed(2) + " Creditworthy : " + this.isCreditAvail;
};

document.write(cust2.toString());

</script>

<!-- ---------- FORM VALIDATION ---------- -->

<div>
Enter your name:

<!-- When they leave the input send a reference to the input element, and a reference to the hel error span -->
<input id="name" name="name" type="text" size="30" onblur="isTheFieldEmpty(this, document.getElementById('name_help'))" />
<span id="name_help"></span>
<!-- this is the id number for the text box -->
</div>

<div>
Enter your street address:
<input id="street" name="street" type="text" size="30" onblur="isAddressOk(this, document.getElementById('street_help'))" />
<span id="street_help"></span>
</div>

<div>
Enter your city:
<input id="city" name="city" type="text" size="30" onblur="isTheFieldEmpty(this, document.getElementById('city_help'))" />
<span id="city_help"></span>
</div>

<div>
Enter your state code:
<input id="state" name="state" type="text" size="2" onblur="isStateOk(this, document.getElementById('state_help'))" />
<span id="state_help"></span>
</div>

<div>
Enter your phone number:
<input id="phone" name="phone" type="text" size="15"
onblur="isPhoneOk(this, document.getElementById('phone_help'))" />
<span id="phone_help"></span>
</div>

<div>
Enter your email:
<input id="email" name="email" type="text" size="30" onblur="isEmailOk(this, document.getElementById('email_help'))" />
<span id="email_help"></span>
</div>

<script type="text/javascript">

function editNodeText(regex, input, helpId, helpMessage)

{
  // See if the info matches the regex that was defined
  // If the wrong information was entered, warn them
  if (!regex.test(input)) {

    if (helpId != null)
      // We need to show a warning
      // Remove any warnings that may exist
      while (helpId.childNodes[0]){
        helpId.removeChild(helpId.childNodes[0]);
      }

      // Add new warning
      helpId.appendChild(document.createTextNode(helpMessage));

    } else {

      // If the right information was entered, clear the help message
      if (helpId != null){

        // Remove any warnings that may exist
        while (helpId.childNodes[0]){
          helpId.removeChild(helpId.childNodes[0]);
        }

      }

    }
}

// inputField – ID Number for the html text box
// helpId – ID Number for the child node I want to print a warning in
function isTheFieldEmpty(inputField, helpId) {

  // See if the input value contains any text
  return editNodeText(/^[A-Za-z\.\' \-]{1,15}\s?[A-Za-z\.\' \-]{1,15}\s?[A-Za-z\.\' \-]{1,15}/, inputField.value, helpId, "Please enter a valid name.");
}

// inputField.value – Value typed in the html text box
function isAddressOk(inputField, helpId) {

  return editNodeText(/^[A-Za-z0-9\.\' \-]{5,30}$/, inputField.value, helpId, "Enter a Street (Ex.1234 Main St.)");
}

function isStateOk(inputField, helpId) {

  return editNodeText(/^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/, inputField.value, helpId, "Enter a State Code in Uppercase (Ex.NY, PA, CA)");
}

function isPhoneOk(inputField, helpId) {

  return editNodeText(/^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$/, inputField.value, helpId, "Enter a Phone Number (Ex.412-828-3000)");

}

function isEmailOk(inputField, helpId) {

  return editNodeText(/^[A-Za-z0-9._-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/, inputField.value, helpId, "Enter an Email (Ex. derekbanas@newthinktank.com)");

}

</script>

<!-- ---------- EXCEPTION HANDLING ---------- -->

<script type="text/javascript">
// Through exception handling we can catch and manage errors rather then
// crashing by surrounding problem code in a try block and handling it
// in a catch block

var custArray = ["Tom", "Bob", "Sally", "Sue"];

var getCust = function(index){
  if(index > custArray.length){
    throw new RangeError("Index must be >= 0 and <= " + custArray.length );
  } else {
    return custArray[index];
  }
}

try {
  document.write("Customer : ", getCust(5), "<br />");
}
catch(ex){
  if (ex instanceof RangeError){
    document.write(ex.message + "<br />");
  }
}

</script>

  </body>
</html>