HTML 5: When to use or

tl:dr

  • <a> is used for page navigation
  • <button> is used for actions on the page
  • <input type="button" /> is used in a form and the value is used in the form

The Problem

Let’s take a look at this small piece of code:

<a id="btn" class="btn btn-default">Button</a>
<script>
  var btn = document.getElementById('btn');
  btn.addEventListener("click", function(e){
    e.preventDefault();
    console.log('awesome btn action');
});
</script>

Now half of the people I showed this piece of code, said: well there is nothing wrong with the code. That is a perfectly fine way of defining a button.

If you take a closer look, you will discover a couple of smaller issues with this piece of code.

First, you would notice that hovering over the button you get a text cursor instead of a ‘hand’-cursor. This is caused by leaving the attribute “href” undefined, you can fix it via defining something like ‘#’ or via CSS.

Then you would notice that by defining the “href” tag you would cause the browser to navigate to another page or the top of the page. To prevent this you would then need to add some Javascript code and call ‘event.preventDefault()’, or add to your previous hack and define the href as ‘#0’. This solves the problem by relying on the browser not knowing what to do with illegal element ids (ids can never start with a number).

Voila, you are now in the situation that you are using some hack pattern that degrades the readability of your code. Someone may come along and assume that someone made a mistake defining the href attribute /or used a placeholder and forgot to replace it.

The Solution

Now let’s improve the readability of the code:

<button id="btn" class="btn btn-default" type="button">Button</button>
<script>
  var btn = document.getElementById('btn');
  btn.addEventListener("click", function(){
    console.log('awesome btn action');
});
</script>

We are now using the correct tag <button>, no need for any hacks to fix the cursor or some wierd href, and no additional line of Javascript. You will need CSS to ensure that the button looks the same in all Browsers, however you would probably anyway used CSS to style your <a>-button.

But what about IE8? – for that we set the type=’button’, and IE8 is almost of no concern anymore (even for big corporate customers)

<button> vs <input type="button" />

Both types of buttons work in practice the same way. However, the Button element allows you to add content elements, like an image. And usually, you would use the <input type="text" /> tag in a </button>`.

As we are not working with a form and just want to have a button to execute some JS-Code I would use the Button tag.

Summary

  • <a> is used for page navigation
  • <button type="button"> is used for actions on the page, can contain other HTML elements
  • <input type="button" /> is used in a form

Some More Reading

Image: Designed by Freepik

JSP: Passing Variable Data to JavaScript

When you try to marry old JSP Technology with the modern wonders of Typescript/ES6. You will want to expose some data provided by the backend into the JavaScript. If you have the possibility you would use a fetch()call to receive JSON. Sometimes, it is not possible to do a big rewrite of the JSP to fix a minor bug. Here is a very dirty way to pass data from the JSP into the JS code. This code will utilize the HTML5 data-attribute. Learn more about it here

JSP File:

<fmt:message var="someText" key="core.someText" />

<div id="jsVariables"
     data-someText="${self.someText}"
    >
</div>

JavaScript:

let dataContainer = document.getElementById('jsVariables');
let someText = dataContainer.dataset.someText;

JQuery:

let someText = $('#jsVariables').data('someText')

This is a very elegant solution (for well I guess using JSPs), now you can run ESLint on your Javascript Code and will not have any unresolved variables.

Bioshock – Remove Intro Videos (Steam)

Bioshock Remastered – Updated Graphics, but same old stupid multiple unskippable 2k Intro Video. Great…

To avoid waiting for ages to get the stupid game going. You can add a the flag -nointro to the launch options.

  1. Right-click on the game in the steam library and select “Properties”
  2. Then click on the button “Set Launch Options”
  3. Add the flag “-nointro”

Udacity – Web Tooling and Automatisation

I recently took a look at the course materials for Web Tooling and Automatisation.

Overall the course is very well structured and introduces Gulp and a couple of common packages used in web development. Besides their main topic, they cover topics on good engineering practices, like linting and testing to ensure code quality.

While working on the project I ran into several little smaller things that were quite annoying. Thankfully the gulp community is quite big, so somebody already solved some of the issues I was facing.

Passing an “–production” flag

When developing, you will probably create a version of your software that is suited for easily finding bugs and errors and an optimized version that is minified and optimized for optimal performance for the end user.

You would define two different tasks in gulp, one “default” and one “production” task. This, however, would, in turn, cause you to have to duplicate your code – with optimization and without.

I found the package “gulp-if” that allows you to control if a function like compression is active during the task. The remaining issue was to actually set the parameter before the tasks run. (All tasks in gulp run in parallel).

To get a flag from the command line, you can use the process.argv Array. However, you must add “–” before your flag name. If not gulp will assume it is another task name that should run.

In the end, you would use something like this:

//Enable Production Flag
var production = (process.argv.indexOf("--production") !== -1);

//Use in task

gulp.task("default", ()=>{
  gulp.src(path.src);
.pipe(gulpif(production, foo())
.pipe(gulp.dest(path.dest));
});</pre>
**Note:** In Gulp 4, you can use a sequencer and would not need to pass in the flag by command-line, but you would define a task that will run before all the other tasks.

# Dealing with Asset sources and destinations
When using gulp.src() and gulp.dest(), typically people use strings to define the locations. However, this is quite annoying if you want to get a quick overview which locations are used. For a better maintainability, you should create a small variable block that defines these strings. In the long run, it lets you be more flexible where your files are etc.
<pre class="lang:js decode:true ">//Path Definitions
const htmlPaths = {
    src: "src/views/**/*.pug",
    dest: "dist"
}

gulp.task("html", () => {
    gulp.src(htmlPaths.src)
        .pipe(pug())
        .pipe(gulp.dest(htmlPaths.dest))
});

End Result

At the end of the course, I ended up with this gulpfile.js. It adds support for Typescript, Pug(Jade), google-closure-compiler.

The common gulp tasks to run are:

  • gulp serve: Uses browser-sync with CSS injection for live-editing
  • gulp --production: Creates an optimized build

Next steps: Depending on your web server, you would want to add a gulp deploy task.

gulpfile.js

//Gulp Packages
const gulp = require('gulp');
const gulpif = require('gulp-if');
const browserSync = require('browser-sync').create();

const pug = require("gulp-pug");

const imagemin = require('gulp-imagemin');

const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");

const ts = require("gulp-typescript");
const eslint = require("gulp-eslint");
const closureCompiler = require('google-closure-compiler').gulp();

const jasmine = require("gulp-jasmine-phantom")

//Flag Definitions
var production = (process.argv.indexOf("--production") !== -1);


//Path Definitions
const htmlPaths = {
    src: "src/views/**/*.pug",
    dest: "dist"
}

const stylesPaths = {
    src: "src/styles/**/*.scss",
    dest: "dist/styles"
}

const scriptsPaths = {
    src: "src/scripts/**/*.ts",
    dest: "dist/scripts"
}

const imgPaths = {
    src: "src/img/*",
    dest: "dist/img"  
}

//Task Definitions
gulp.task("default", ["html", "scripts", "styles", "images"]);

gulp.task("serve", ["default"], () => {
    browserSync.init({
        server: "./dist"
    });
    gulp.watch(srcStyles, ["styles"]);
    gulp.watch(srcScripts, ["scripts"]);
    gulp.watch(srcImages, ["images"]);
    gulp.watch(srcHTML, ["html"]).on('change', browserSync.reload);
})

gulp.task("html", () => {
    gulp.src(htmlPaths.src)
        .pipe(pug())
        .pipe(gulp.dest(htmlPaths.dest))
});

gulp.task("scripts", () => {
    gulp.src(scriptsPaths.src)
        .pipe(ts({
            out: "output.js"
        }))
        .pipe(eslint({
            parser: "typescript-eslint-parser"
        }))
        .pipe(eslint.format())
        .pipe(gulpif(production, closureCompiler({
            compilation_level: 'SIMPLE',
            warning_level: 'VERBOSE',
            language_in: 'ECMASCRIPT6_STRICT',
            language_out: 'ECMASCRIPT5_STRICT',
            output_wrapper: '(function(){\n%output%\n}).call(this)',
            js_output_file: 'output.min.js'
        })))
        .pipe(gulp.dest(scriptsPaths.dest));
});

gulp.task("styles", () => {
    let sassOptions = {};
    if (production) {
        sassOptions = {
            outputStyle: 'compressed'
        }
    }
    gulp.src(stylesPaths.src)
        .pipe(sass(sassOptions).on('error', sass.logError))
        .pipe(autoprefixer({
            browsers: ['last 2 versions']
        }))
        .pipe(gulp.dest(stylesPaths.dest))
        .pipe(browserSync.stream())
});

gulp.task("tests", () => {
    gulp.src("src/tests/test.js")
        .pipe(jasmine({
            integration: true,
            vendor: '_build/**/*.js'
        }))
})


gulp.task("images", () => {
    gulp.src(imgPaths.src)
        .pipe(imagemin())
        .pipe(gulp.dest(imgPaths.dest));
})

Package.json

{
  "name": "udacity-webtooling",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.18.7",
    "eslint": "^3.15.0",
    "eslint-config-google": "^0.7.1",
    "google-closure-compiler": "^20170124.0.0",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.1",
    "gulp-eslint": "^3.0.1",
    "gulp-if": "^2.0.2",
    "gulp-imagemin": "^3.1.1",
    "gulp-jasmine-phantom": "^3.0.0",
    "gulp-pug": "^3.2.0",
    "gulp-sass": "^3.1.0",
    "gulp-tslint": "^7.1.0",
    "gulp-typescript": "^3.1.4",
    "phantomjs": "^2.1.7",
    "tslint": "^4.4.2",
    "typescript": "^2.1.6",
    "typescript-eslint-parser": "^1.0.3"
  }
}

Sources:

ImageDesigned by Freepik

CodeWars Kata: File Path Operations

The quick Code Wars Kata I am taking a look at the Kata File-Path-Operations.

My approach to solving the kata was, first to figure out what skills are needed to solve the problem. Since all three problems are similar and try to find a specific pattern in a string, the obvious answer is Regular Expressions.

The fastest way to learn, create and test your Regular Expressions is using Regex 101.

I solved the Kata using Typescript and this is my final code:

export class FileMaster {

  constructor(private filepath:string) { }

  extension() {
   return this.filepath.match(/\.(.*)/)[1];
  }

  filename() {
   return this.filepath.match(/\/([^\/]*)\./)[1];
  }

  dirpath() {
   return this.filepath.match(/(.*\/)/)[1];
  }
}

This piece of code would not be suitable for production. It does not take into account of malformed filenames, it would not work for windows; It would have problems with folders that contain a “.” etc.

If you would be using NodeJS you would use the existing functions in the Path Module.

Elementary OS: Things to do after installing Elementary OS 0.4 (Loki)

When you start out with elementary OS there are a couple of useful things that you should do to have a better experience working with your system.

General

“Software & Updates” for Additional Drivers

The easiest way to install the proprietary nVidia Drivers (in Ubuntu) is to go to System Settings > Additional Drivers and then simply select the driver.

This option is not available in Elementary. However, by installing the package software-properties-gtk you can get the program.

sudo apt install -y software-properties-gtk

Now by clicking on Applications on the top right, and then type “Software & Updates” you can access the Settings.

Easy way to add PPA

With the command line tool add-apt-repository you have a quick way to add additional PPA’s. To get this tool you need to install the package

sudo apt-get install software-properties-common

Add a Minimize Button to Windows

Some of the Elementary Windows do not have an easy way to minimize the window.  With Elementary Tweaks you can add a button to the windows.

Officially the elementary team does not encourage users to use the tweaking tool, since it also exposes switches to functionality that could mess up your system, so use the tool with caution.

sudo add-apt-repository ppa:philip.scott/elementary-tweaks
sudo apt install elementary-tweaks

Microsoft Font Compatability

sudo apt-get install ttf-mscorefonts-installer

Replace Screenshot tool

sudo apt remove screenshot-tool
sudo add-apt-repository ppa:shutter/ppa
sudo apt-get update && sudo apt-get install -y shutter

Chrome

wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
sudo apt-get update
sudo apt-get install google-chrome-stable

Skype

wget https://go.skype.com/skypeforlinux-64-alpha.deb
sudo dpkg -i skypeforlinux-64-alpha.deb

Office

sudo apt install libreoffice

Graphic Editors

sudo apt install gimp inkscape shutter

Video

Video Lan

sudo apt install -y vlc

Codecs

sudo apt-get install ubuntu-restricted-extras ffmpeg

Other

Redshift

A simple program to prevent Eye Strain

sudo apt install redshift gtk-redshift

Laptop Battery Saver

sudo apt install tlp tlp-rdw

Last Steps

Remove Programs

sudo apt remove pantheon-mail -y
sudo apt remove maya-calendar -y
sudo apt remove epiphany-browser -y
sudo apt remove audience -y

Update your system

sudo apt-get update && sudo apt-get dist-upgrade

Some content has been disabled in this document

Notes on MITx: 6.005.1x Software Construction in Java (Week 2)

This week the course is covering another two very important topics: Testing and Specifications.

LECTURE 3: Testing

Testing is a very important part of creating functionally correct programs.

Testing will be always incomplete

You will try to test your program using three methods:

  1. Formal Reasoning, essentially you manually verify that your program works correctly
  2. Code Review: Another Programmer takes a look and says everything is ok.
  3. Test Suites: Essentially you write another program (which can have its own bugs) to test your program. You define the inputs and the expected output and compare them.

The course mentions again the residual defect rates of 1-10 defects/kloc(1000 lines of code). Again this does not cite where this number actually comes from. Especially when using Industry Standards and Test Suites this high number would drastically drop to a much lower number. However, in the end, it only would remain to be an assumption since the actual number cannot be determined. You testing your program for every possible input (Exhaustive testing) is not feasible. The strategy to simply take a look and see if it works (Haphazard testing) will also not reveal all bugs. The same is true for “Random” testing. All of these test methods cannot be used to test software.

Write Tests

When you are writing tests you should think about how you can make your program fail. Test drive development takes the following approach.

  1. Specify what you want to program
  2. Write tests that would test the specification
  3. Write code so that your code passes the tests

The specification is key to define what inputs are possible and which outputs will be produced. (This also includes throwing errors) Blackbox testing only focuses on the input and output of the function. These tests do not take into account how the algorithm actually works. The alternative is Whitebox testing takes into account how the program is implemented.

Test Coverage

Now that you have written tests for all of your code, did you also test all of your code? Coverage takes a look at if all Statements and all possible paths through your code are covered. There are various Code coverage tools available that you can run and then visually see which part of the code is covered by your tests. In reality, you should try to achieve a coverage of 70-90% of your code achieving 100% is usually not possible due to time constraints. Of course, this is not the case if you are using Test Driven Development.

Running Tests

Usually, you would create a testsuite of Unit Tests. You should integrate these tests into your build process to ensure that the tests run automatically. Especially when you modify existing code this will ensure that your modifications will not accidentally break something unintentionally. When working with multiple people you should add hooks to your git repository that it rejects code that does not pass your test suite.

LECTURE 4: Specifications

This lecture is going to cover preconditions and post-conditions in method specifications, and how to write correct specifications.

What is a specification?

The lecture defines a specification primarily only concerning how the interfaces are defined and how the specification document essentially is used as a communication device to talk to the client. Now, this actually assumes that the client is another programmer that wants the module/system to do a specific functionality. In my work experience usually, the client has no technical background and expects the programmer to know what he wants.  Yes, the specification is the key document on how to negotiate which features etc. the client requires, it is however not exactly defined which functions or how interfaces should be created, this is usually the task of the programmer. The course actually is more talking about a documentation document how and which interfaces exist in the code you are programming for the client. The documentation is key whenever other programmers need to use the code you have programmed. In either case, the specification document is a key document. It defines the work that needs to be done. The document shields the programmer from the client, if the client forgot to specify something, thus the programmer did not implement it he can prove it was the client’s fault. At the same time, the programmer is bound to the document that he actually implements all features. (or negotiates, talks with the client that the functionality is unfeasible, or not possible to be implemented)

Pre and Post Conditions

For each function, you require the preconditions (what inputs) and postconditions (what outputs). The inputs may have to have a specific structure, cannot be a certain value etc. These need to be checked. The function also will have various outputs. This is, of course, the result, and how the result should be structured, the method also can throw errors.

Write test cases

Essentially if the specification of the function is well defined it is very easy to write the test cases. You simply follow the specification write tests to get the expected correct results and willfully pass wrong arguments into the function. The rest of the lecture covers how to throw Exceptions. Which to use when.

HOMEWORK

Again another batch of “Java Tutor” exercises. They were as exciting as the last batch… However this time they also provided a “warm-up” problem set. The warm-up is just to implement the mathematical “quadratic roots formula”. The straightforward implementation of the formula will not pass all the Unit Tests. You need to take a deeper look at Java to actually figure out why the last Unit Test fails, and how you can change your code to make your code pass the test.

Elementary OS: Windows Apps with Play on Linux

One of the major issues when using Linux is that you would like to use Software that was written for Windows. Thankfully more and more new Software is cross-platform compatible. However especially older Software and most newer Games will not support Linux.

If you are dependent on using Windows Software then you have several options available. Dual-Boot Windows and Linux, use a Virtual Machine (like VirtualBox or try  WineHQ

Wine essentially translates the Windows Commands to Linux Commands at run-time. Eliminating the penalty of using a virtual machine. The downside of Wine is, that not all new programs run properly. However, it seems games that were written for Windows XP work better with Wine than with Windows 10.

The last time I was playing with Linux I found it very difficult to configure and find packages. You need wine, wine-tricks, then install some other windows package into wine etc.  This time I found another project Play on Linux that provides an easy to use GUI with quick Installers for many different programs.

The other thing which makes “Play on Linux” great, is that it can create multiple virtual drives, for your various programs. So you can use different versions of Wine, or configure the different drives to emulate a different version of Windows, use different components etc.

Install Play on Linux

wget -q "http://deb.playonlinux.com/public.gpg" -O- | sudo apt-key add -
sudo wget http://deb.playonlinux.com/playonlinux_trusty.list -O /etc/apt/sources.list.d/playonlinux.list
sudo apt-get update
sudo apt-get install playonlinux

Battle.net games

Play on Linux shines the most when it already provides an installer that automatically configures Wine correctly to install all components that the program simply runs without any additional work.

You just locate Hearthstone, Diablo or Starcraft from the list and press install and the program will work without any issues.

Windows Steam Games

Step 1#

Install Windows Steam. Play on Linux provides easy installers for Steam, simply search for steam in the installer menu and press install.

Step 2

You will have to look up in the Wine AppDB if your game is supported by Wine.

If it is supported you then can log into steam and install games from your library just like in windows.

Step 3

Usually, you will need to install some sort of additional windows package to get the program running.

In my case, I wanted to install Tron 2.0, in the documentation for the program. Something like needs “winetricks directmusic” was mentioned.

To install “directmusic” you need to select Steam and click on Configure. Then switch to the Install components Tab and then select the component from the list and press install.

In some cases, like with my Tron 2.0 example, this is not enough and you have to google some more to find some helpful [article] (http://www.gamersonlinux.com/forum/threads/tron-2-0-guide.628/) that then tells you to install additional components  and not to use the Windows XP emulation but the Windows 7 emulation.

Custom Installers

Of course, you may have your own Programs, you can simply click on “Install non-listed program” navigate to the installation files and install your program.

Access to Files

Play on Linux installs a handy shortcut into your home directory so that you can easily access the various virtual hard drives of the Play on Linux instances, if you have the need to copy&modify files.

Conclusion

While Wine is not perfect and not everything runs smoothly and out of the box like when using Windows directly. It is worth fiddling around with Wine/Play on Linux to not have to dual boot or get a VM running.

Notes on MITx: 6.005.1x Software Construction in Java (Week 1)

MITx has released a course titled “Software Construction in Java”. The course is aimed at more experienced Developers and is going to teach a couple of general principles of Software Development.

The course has the goal that you develop good code, which is defined as:

  • Safe from bugs: Correct behavior of the code, now and in the future
  • Easy to understand: Code should be easily understandable by other developers
  • Ready for change: Architectural patterns that allow you to modify the code without major rewrites.

Over the next couple of weeks, I will complete this course and will publish my notes and thoughts on the material. You can also take the course at https://www.edx.org/course/software-construction-java-mitx-6-005-1x

Why am I taking this course?

I have worked with Java in the past. I do not prefer using the language. However in the Python course from MIT was fantastic and thought very interesting concepts that apply to all languages. My hope is that this course will teach broader concepts and the language they are using just happens to be Java.

Lecture 1: Overview + Static Typing

The first lecture i skipped most of the videos, they seemed more like an introduction to Javas static typing, which I was already familiar with.

Lecture 2: Code Review

The second lecture takes a look at good Coding Practices.

Code Review

Lecture notes: The purpose of a code review has two main goals:

  • Improve the code
  • Improve the programmer

Personal notes: In reality on many programming projects the “Code Review”- Phase is cut due to budget constraints, lack of time and personal feelings. Remember when you do a code review you may hurt the feeling of another programmer, who thinks he is infallible. This usually causes that more and more bad code is written. Making the project not maintainable and unreliable. If it is possible for your project to do Code Reviews, you defiantly should do them, and have a very specific action plan that the other developer can learn from his mistakes.

Style Standards

Lecture notes: You can find good style guides at https://github.com/google/styleguide

Personal notes: Every programmer has his personal style how he likes to format and read his code. All university classes (including this one) do not provide a style guide. With the consequence that also no style guide is enforced. In larger projects this would not be possible. The version control systems suddenly cause problems, create merge conflicts etc. Styleguides should never be manually enforced. That would be tedious and create a lot of unnecessary work. The guide should be enforced by your build process. This prevents programmers from using their own style guide, avoids merge issues, is easier to manage, and it is psychologically better for the programmer that the machine rejects code rather than another programmer. The best practice would be that every code commit gets checked prior to be allowed into the repository. This ensures that every developer is playing by the same rules. (To find more information on this subject google for “git hooks” and “java checkstyle”)

Code Smells

  • Don’t Repeat Yourself (DRY)
  • Comments where needed
  • Fail fast
  • Avoid magic numbers
  • One purpose for each variable
  • Use good names
  • No global variables
  • Return results, don’t print them
  • Use whitespace for readability

Personal notes: While the lecture presents various strategies to prevent the most common beginner mistakes. These are just a select few of all the various types of code smells. I prefer to use the IDE IntelliJ, it has a feature called “Code Inspector”. It will scan your code and suggest fixes for a lot of types of code smells. Good code should never have obvious code smells.

Homework

For the “Java Tutor” Homework assignments you must use an Eclipse Plugin.  So sadly you have to use Eclipse with a custom built plugin and as usual I have had a lot of fun with randomly crashing Eclipse, the plugin giving me over and over again the same questions. The “Java Tutor” is overall quite weak. The questions are more like “fill in the blanks” and only accepts a single correct answer. Usually the titles of the links to the related materials give away the correct answer. However if you enter the wrong value, you can simply click “Show Answer”, copy the solution and progress without penalty.

Elementary OS: Loki

Elementary OS is a new Operating System that wants to be an alternative to Window or OSX. The team behind the project puts a high emphasis on Usability and Design.

Over the next couple of days, I will try to actually switch to the system. Elementary is based on Ubuntu, which in turn is based on Debian, so all *.deb packages and programs can be installed without any problems. As with all Linux, Distributions Elementary is free. However, the developers require you to think about it if you would like to support their efforts or not. If not you enter a 0 into the download field.

For my initial setup, I will essentially install all the common programs I use on a day to day basis.

How To install Elementary.io

Step 1 Download the ISO

Go to www.elementary.io and download the current Version. If you have some money to spare you can donate to the project. If not enter a 0 and you can download the iso for free.

Step 2: Prepare a USB Stick

Go to https://rufus.akeo.ie/ and download the Rufus tool, this allows you to easily create a bootable USB stick.

Step 3: Install

Well for the last step you really just have to boot from the stick and follow the instructions.

First Steps

Remove Default Programs

The team focuses a lot on providing a suite of programs that also follow it’s design principles.

I would prefer to use Chrome as my Browser, and VideoLan for videos and I do not need an email client or a dedicated calendar.  I removed them with these commands:

sudo apt remove pantheon-mail -y
sudo apt remove maya-calendar -y
sudo apt remove epiphany-browser -y
sudo apt remove audience -y

(The program “audience” is the default video player)

Install General Programs

Chrome

Since Chrome has some Google stuff in it you first have to add it to apt with this command:

wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
sudo apt-get update
sudo apt-get install google-chrome-stable

VideoLan

To install VideoLan simply enter the following command:

sudo apt-get install vlc -y

###Skype Microsoft has just recently announced that they will create a Skype Client for Linux. For now, there is only the official “Skype for Linux Alpha”. Essentially the program is still barebones and is in very early stages of development. – If you install it do not expect that everything will be working.

wget https://go.skype.com/skypeforlinux-64-alpha.deb
sudo dpkg -i skypeforlinux-64-alpha.deb

Shortcuts

| Shortcut | Command | | ==== | ==== | | ⌘+Space | App Launcher | | Alt+Tab | Window Switcher | | ⇧+Alt+Tab | Switch Windows Backwards| | ⌘+Left/Right | Switch Workspace | | ⌘+S | Workspace Overview | | Ctrl+⌘+Left/Right | Snap Window to Half of Workspace | | ⌘+T | Terminal |

Conclusion

The OS looks awesome, it feels like a system you actually could work with for a longer period of time. In the past, I have always tried Linux for a couple of days and then said, well interesting, but a lot of my programs simply do not work and I would like to go back to Windows.

Let’s see how long this time the experiment is going to last and if Linux has become more user-friendly over time.