Starbeamrainbowlabs

Stardust
Blog


Archive


Mailing List Articles Atom Feed Comments Atom Feed Twitter Reddit Facebook

Tag Cloud

3d 3d printing account algorithms android announcement architecture archives arduino artificial intelligence artix assembly async audio automation backups bash batch blender blog bookmarklet booting bug hunting c sharp c++ challenge chrome os cluster code codepen coding conundrums coding conundrums evolved command line compilers compiling compression conference conferences containerisation css dailyprogrammer data analysis debugging defining ai demystification distributed computing dns docker documentation downtime electronics email embedded systems encryption es6 features ethics event experiment external first impressions freeside future game github github gist gitlab graphics guide hardware hardware meetup holiday holidays html html5 html5 canvas infrastructure interfaces internet interoperability io.js jabber jam javascript js bin labs latex learning library linux lora low level lua maintenance manjaro minetest network networking nibriboard node.js open source operating systems optimisation outreach own your code pepperminty wiki performance phd photos php pixelbot portable privacy problem solving programming problems project projects prolog protocol protocols pseudo 3d python reddit redis reference release releases rendering research resource review rust searching secrets security series list server software sorting source code control statistics storage svg systemquery talks technical terminal textures thoughts three thing game three.js tool tutorial twitter ubuntu university update updates upgrade version control virtual reality virtualisation visual web website windows windows 10 worldeditadditions xmpp xslt

Adding a New Samba User

I found myself looking up how to create a new user in samba for about the 5th time today, so I tought I'd post about hwo to do it here so I don't forget :P

Starting from version 4, from what I can tell, Samba doesn't use the local unix accounts on your system. You need to create Samba accounts instead.

To do this, run the following command:

sudo smbpasswd -a username

Then type and retype the password you want for the new account. Note that you need to have a local unix account created under the same name as the samba account that you want to create. If you don't want a real account under the name of the samba account that you want to create, you can create a 'dud' account without a home directory or shell like so:

sudo useradd username --shell /bin/false

I hope this helps someone besides myself. If it did, try commenting below. You don't need an account, and you don't have to provide your email address either (though I seriously won't spam you at all if you do provide it!).

Ubuntu: Second Impressions

Ubuntu's Default Background I've had my laptop dual booted with Ubuntu for a while now, and I've been using Ubuntu in a Virtual Machine and as a live CD, but I've only just gotten around to rearrenging my partitions and reimaging my Ubuntu partition with Ubuntu 15.04. Previously, I had a bunch of issues with ubuntu (for example my laptop kept heating up), but I seem to have solved most of them and I thought that I'd post here about the problems I encountered, how I fixed them, and what I think of the latest version of ubuntu.

Firstly, I installed ubuntu from a live CD iso on my flash drive. Annoyingly, I used the 32 bit version by accident, and had to do it again. It would be nice if it told you which version you were about to install. Anyway, I found the installer to be rather temperamental. It kept freezing for ages, and all I could do was wait.

After the installation finished, I was left with a brand new, and very buggy, 64 bit Ubuntu 15.04 installation. As soon as it booted, the first job was to stop my cursor from flickering. Because I have an Nvidia GeForce 550M GPU, Ubuntu didn't recognise it properly (it detected it as a second 'unknown display') and so custom drivers were needed to fix it. I found this post, which guided me through the installation of both bumblebee (to control which of my two GPUs I use), and the official Nvidia drivers for my graphics card.

After banishing the flickering cursor, I found my laptop cooler, though it still wasn't right. Next up was to install thermald, indicator-cpufreq and lm-sensors. This trio of packages automatically controls the frequency of your CPU to both save power and prevent overheating. Normally, linux doesn't pay any attention to the frequency of the CPU of it's host system, leaving to run at it's maximum speed all the time - which causes battery drain and overheating.

Now that my laptop wasn't overheating too much, I could focus on other problems. When in Windows 7, I have something called SRS Premium Sound. It is brilliant at tweaking audio just before it reaches the speakers to improve it's quality. I quickly found when I got this laptop that it was essential - the speakers are facing downwards and the output sounds 'tinny' or 'hollow' without it. Since linux doesn't have SRS, the next best thing was PulseAudio, which provides you with an equaliser to tune your sound output with. Note that PulseAudio does actually work with Ubuntu 14, even though some people have said that it has been discontinued (I don't think it has?).

The other thing that needed changing was my touchpad. I felt like I had to hammer it in order to get it to recognise my touch, whereas in Windows it picked up the lightest of touches. My solution was to add the following to my .profile:

synclient FingerLow=2
synclient FingerHigh=3
synclient AccelFactor=0.145
synclient TouchpadOff=0
synclient MinSpeed=1.25
synclient MaxSpeed=2
synclient CoastingFriction=30

This improved the responsiveness of my touchpad a whole lot to the point where I could actually use it without getting frustrated :)

That covers the main problems I came across. As for what I think, I'm finding Ubuntu to be a great operating system to work with - now that I've worked most of the bugs out. Things like indicator-cpufreq and thermald ought to be automatically installed on systems that support them at install time. You should also be prompted to install bumblebee and the offical nvidia graphics drivers at install time too, as a system with multiple GPUs (i.e. integrated graphics and a graphics card) are pretty unusable without them. Sensible default settings would be nice too - nobody likes hammering their touchpad just to get a response.

The Ubuntu unity desktop developers seem to have remvoved a bunch of configuration options from the GUI in recent releases. Hopefully they wil readd them - it's rather annoying to have to enter the terminal to change something as simple as the login screen background.

On the plus side, Ubuntu seems to load much faster than Windows 7, and is more responsive too. I also feel like I have more screen space to work with as there isn't a task bar taking up space at the bottom of the screen. The customisability is amazing too. I am finding that there are far more things that you can tweak and fiddle with in Ubuntu compared to Windows.

To finish off this post, here's a list of smaller problems I had, and a link to the appropriate post that fixed it for me:

End of ES6 Features Series

This post marks the end of my Ecmascript 6 features series of posts for now. While there are a few more topics I could cover, I don't feel that there is enough support in today's javascript engines to do them justice. At some point in the future I will come back to this series and finish off those topics that I've skipped out on this time.

Before I end this series though, I found a Javascript feature support table that you might find useful. It shows you which ES5/6/7 features are supported by which browsers and preprocessors.

Ecmascript compatibility table

That's all for now! Here's a list of all the posts that I've made so far in this series.

C♯'s String.Format: A (hopefully) complete tutorial

For a while now whenever I've been formatting strings I've been using the String.Format() method that's built into C♯. Recently, I found it's documentation page, and found that I didn't know the half of what it was capable of, so I decided to learn all of it's tricks and write a tutorial for this blog at the same time. Firstly, here's an example of it in action:

int number = 4626;
string textLine = String.Format("The number is {0}", number);
Console.WriteLine(textLine);

You can pass a number of variables in after the string's format, and they can be referenced in the string itself through the curly braces syntax: {0}. 0 refers to the first variable, {1} to the second, etc. Anything you pass in will have it's .ToString() method called, so you can control how your classes are represented.

We can go one better than the above though. The Console.Write() and Console.WriteLine() methods have String.Format() functionality built in, so we can shorten the above down to 2 lines:

int number = 4626;
Console.WriteLine("The number is {0}", number);

Logging a table of data to the console? You can also pad any variable to make it a given length. Just add a comma and then the length that you want it to pad shorter strings to:

Random rng = new Random();
for(int i = 0; i < 100; i++)
{
    Console.WriteLine("{0,4}: {1}", i, rng.Next());
}

The above will output something similar to this:

   0: 1386044068
   1: 337840762
   2: 796579848
   3: 2124870500
   4: 1451010095
   5: 2086322183
   6: 2057125438
   7: 1856321748
   8: 1688522403
   9: 982979897
  10: 1571218679
  11: 1851393877
  12: 572762676
  13: 549024616
  14: 1496101994
...

By default, it pushes things to the right, but you can make it do the opposite by adding a minus sign to the padding length. So if you wanted to push the first variable to the left and have a minimum length of 4, it would be {0,-4}.

It doesn't stop there though. For numbers, you can convert can control the number of decimal places that are displayed. This is done like this:

Random rng = new Random();
for(int i = 0; i < 100; i++)
{
    Console.WriteLine("{0,4}: {1:0.00}", i, rng.NextDouble());
}

Notice that we're using a colon instead of a comma here. The above will output something like this:

   0: 0.86
   1: 0.91
   2: 0.97
   3: 0.41
   4: 0.70
   5: 0.81
   6: 0.26
   7: 0.73
   8: 0.93
   9: 0.14
  10: 0.80
  11: 0.71
...

You can even automatically convert a number to a percentage by adding a percent sign (%), and it will automatically be multiplied by 100:

Random rng = new Random();
for(int i = 0; i < 100; i++)
{
    Console.WriteLine("{0,4}: {1:0.00%}", i, rng.NextDouble());
}

Then you get an output like this:

   0: 59.62%
   1: 37.75%
   2: 33.98%
   3: 44.40%
   4: 66.73%
   5: 83.00%
   6: 95.67%
   7: 47.98%
   8: 5.05%
   9: 88.48%

If you want to ensure that all the values have the same width (and who wouldn't?), you can combine the two syntaxes like this:

Random rng = new Random();
for(int i = 0; i < 100; i++)
{
    Console.WriteLine("{0,4}: {1,-8:0.00%}", i, rng.NextDouble());
}

The above produces something like this:

...
  12:   36.60%
  13:   60.48%
  14:   13.96%
  15:   36.88%
  16:    6.55%
  17:   89.51%
  18:   19.18%
  19:   91.98%
...

Numbers can also be converted to hex like this:

Random rng = new Random();
for(int i = 0; i < 100; i++)
{
    Console.WriteLine("{0,4}: {1:x8}", i, rng.Next());
}

The above formats the numbers as lowercase hex, and pads them to be at least 8 characters long. Here's what the above might output:

   0: 4d7867e8
   1: 3dc7d06d
   2: 118b1c4b
   3: 5cd477c5
   4: 580a74e1
   5: 69d50a4b
   6: 7ccf118e
   7: 25725808
   8: 093ddea4
   9: 164a7baf
...

Simply change the lowercase x to an uppercase one to change the format to be uppercase. Numbers aren't the only thing that String.Format() lets you play with though. Dates are supported too:

DateTime dt = DateTime.Now;
Console.WriteLine("Day {0:d} of the month of {0:m} the {0:yyyy}th year", dt);
// Output example: Day 04/09/2015 of the month of 04 September the 2015th year

That pretty much concludes this post about String.Format(). If I tried to demonstrate every little feature, we would be here all year! Before I go though, I have put together a quick reference guide on all the different formats that it supports:

Format Example Description
{0} cheese The first variable
{0,8} cheese Pad the first variable on the left to 8 characters
{0,-8} cheese Pad the first variable on the right to 8 characters
{0:0.00} 4.38 Round the first variable to 2 decimal places
{0,6:0.000} 3.432 Round the first variable to 3 decimal places and then pad it on the left to 6 characters
{0:x} efe9a Convert the first variable to lowercase hex
{0:X8} EFE9A Convert the first variable to uppercase hex and then pad it on the left to 8 characters.
{0:d} 06/09/2015 Extract the date part of a DateTime object.
{0:t} 02:19pm Extract the time part of a DateTime object
{0:hh} 02 Extract the hour from a DateTime object
{0:mm} 19 Extract the minute from a DateTime object
{0:ss} 56 Extract the seconds from a DateTime object

{0:dd} | 09 | Extract the day from a DateTime object {0:MM} | 09 | Extract the month from a DateTime object {0:M} | September | Extract the long month from a DateTime object {0:yy} | 15 | Extract the short year from a DateTime object {0:yyyy} | 2015 | Extract the long year from a DateTime object

Update 29th October 2015: A commenter by the name Tom let me know that in C♯ 6.0 and above (that's the .NET framework 4.6+) comes with another handy feature that lets you substitute in the contents of a variable directly. Here's his example:

int number = 4626;
Console.WriteLine("The number is {number}");

The above would output The number is 4626. This also extendes to properties of objects, letting you do something like this:

Console.WriteLine("Account {myAccount.Id} belongs to {myAccount.Name} and contains £{myAccount.Balance}.");

There's also a shorthand version of String.Format. Simply prefix a string with a dollar sign ($) and the string will be pushed through String.Format for you:

string display = $"Launch in T minus {rocket.Countdown} seconds!";
Console.WriteLine(display);

You can find out more here: New Language features of C# 6

Sources

3D Worley Noise with noisebox

Worley Noise Recently, I've been writing a command line noise generation tool in C♯, and I've called it noisebox. Initially I found a few noise generation algorithms that other people had already implemented, so all I had to do was write an extensible interfacde on top of the code I'd found. When I came to Worley noise, I couldn't find an implementation that I could understand (I haven't taken a look at delegates properly yet), so I decided to write my own. It's still got some bugs in it, but I've decided to relase the Worley noise implementation on it's own first, and then I will tidy up a few loose ends and release the full code on GitHub (loko out for a blog post soon!).

Here's a link to a gist of the Worley noise generator: Worley.cs

The imbuilt documentation comments (what do you call them?) should give you enough information to use it, but if you get stuck post a comment below and I will try and help you out.

The code will be released under the Mozilla Public License 2.0.

This post's title include the word "3D" - but the image at the top is very much in 2D. To demonstrate the 3D-ness of the algorithm, I added the --frames and --offset options to noisebox and rendered 1000 frames of noise, and then stitched the together with ffmpeg. I've uploaded the result to youtube.

Using the ca-bundle to prevent certificate errors in curl

When you first download and install curl and you try to request something over https, it's likely that you will get an error along these lines:

curl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

You might think that you can bypass this with the --insecure or -k option, but this is insecure as it means that curl isn't checking the identity of the remote server before downloading the the file in question, leaving you open to a man in the middle attack. The solution: Point curl at a bundle of root certificates that it can use to verify a server's identity.

Since curl doesn't pay attention to the certificate store on windows, we have to provide it with a file that contains these root certificates instead. This can be done by running a script provided by the curl develoeprs that automatically downloads the certificates from Mozilla Firefox's source code and compiles them into a format the curl can understand.

Here's a direct link to the script: mk-ca-bundle.pl

Simply download and run that script, and it will generate a file called ca-bundle.crt in the current directory. Rename it to curl-ca-bundle.crt, and copy it to the directory that you installed curl to. Curl will find it when you next request something over https.

Alternatively, you can set the CURL_CA_BUNDLE environment variable to the full path to the ca-bundle.crt file. If you can't copy it to the folder that you installed curl to.

If you can't run the above script, then you can download a ready-made version from this website. My server will update it automatically at 1am UK time every Saturday.

Here's a link: ca-bundle.crt

Ecmascript 6 Features 12: Strings

Welcome to another ES6: Features post. I think I might be getting to the end of this series soon! Anyway, this week's post is going to be on the new string related additions that have been made in Ecmascript 6. First up is a neww utility method called repeat(). As the name suggests, it duplicates a string a specified number of times:

> "e".repeat(10)
'eeeeeeeeee'
> "=-".repeat(4)
'=-=-=-=-'
> "Precarious Porcupine".repeat(3)
'Precarious PorcupinePrecarious PorcupinePrecarious Porcupine'

No more abusing new Array(length + 1).join(number)! It looks like one of those functions that should have been added a long time ago. As usual, the MDN has a polyfill that you can use.

Next up is a set of functions that make searching for things in strings much easier. There's startsWith, endsWidth and includes, and they all return a boolean:

"porcupine".startsWith("p"); // true
"porcupine".startsWith("pine", 5); // true

startsWith has an optional second argument, which lets you specify an offset from which to begin searching. endsWidth also has an optional second argument, but it lets you limit the number of characters that are searched:

"erroneous elephant".startsWith("waterfront"); // false
"erroneous elephant".endsWith("neous"); // false
"erroneous elephant".endsWith("neous", 9); // true

Lastly, there's includes. It works as you might expect it to, with the optional second argument specifying the offset from which to search:

"catastrophic crocodile".includes("croc"); // true
"catastrophic crocodile".includes("cat", 8); // false

This trio of functions should make complex string manipulation much easier to understand as you don't have to use any more complex indexOf tests anymore.

That concludes thsi ES6: Features post on strings. It seems that readability is a running theme throughout ES6. I hope that in time this makes everyone's javascript much easier to read and debug :)

Ecmascript 6 Features 11: Numbers and Math

Welcome to this week's (rather late - sorry about that! I've been out for much of the week) ES6:Features post. This week, I'll be looking at the ne wadditions to the Number and Math objects.

Firstly, there's a pair of new utility functions that have vbeen added to the Number object called Number.isNaN() and Number.isFinite(), and they can be used (as you might expect) to check to see whether a given number is not actually a number or is infinitely large respectively. Here's a few examples:

Number.isNaN(NaN); // true
Number.isNaN(359); // false
Number.isFinite(9478); // false
Number.isFinite(Infinity); // true
Number.isFinite(-Infinity); // true

The next addition is another checking function that you can use to make sure that a number is within a 'safe' range. The way that javascript interpreters or compilers work means that numbers arree manipulated with a fixed number of bits allocated to represent them. This means that there will be a limit to the size of the number that the interpreter or compiler can accurately represent. Since we have both 32 and 64 bit machines at the moment, this limit moves around from machine to machine - hence the addtion of the following function:

Number.isSafeInteger(56); // true
Number.isSafeInteger(39458634957629746293846); // false

A word of warning though: isSafeInteger, as the name implies, works only with whole numbers - so you'll probably need to run any floats through Math.floor() first, or the next new function that's been added: Math.trunc().

Math.trunc() will drop the fractional part (i.e. anything after the decimal point) of any number passed into it. This can be useful for all sorts of things, including using the function above. At first glance you might think that this function is similar to Math.floor(), but it's not. The difference is that if you feed it a negative number, it still chops the fractional part off, rather than rounding it to the next number down:

Math.trunc(-44.44); // -44
Math.floor(-44.44); // -45

After running a test on jsperf.com, I discovered that the new function is a bit slower than Math.floor and Math.ceil (108M ops/sec vs 116M ops/sec), but this is to be expected with a new function, and the difference shouldn't really be noticeable unless you are doing something really extreme :)

The last new addition is the Number.sign() function. This function is another one for convience. It returns 1 if the number is greater than 0, -1 if the number is less than 0, and 0 if the number is 0 exactly. Here are a few examples:

Number.sign(768); // 1
Number.sign(-356); // -1
Number.sign(0); // 0

That concludes this post about the new number related functions added in ES6. Most of them are for convienence, but they should improve the readability of your code a little bit. At least they aren't as confusing as Symbols! Next time I will probably be looking at the new functions added to the String object.

Creating new Ramdisks Programatically with Imdisk

For a while now I have used Imdisk to create ramdisks to store data temporarily while I experiment with it. Imdisk is a driver for windows systems that allows you to create virtual drives that are stored either in memory, or in a file on your hard drive. It also allows you to mount existing images stored in iso or img files to let you explore their contents, for example.

Mounting a new ramdisk with Imdisk

Since I use ramdisks so often, I have written a batch script that automates the process of creating a ramdisk, and I thought that I would share it here:

@echo off

:: BatchGotAdmin7
:: From http://stackoverflow.com/a/10052222/1460422
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
echo Requesting administrative privileges...
goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B

:gotAdmin
pushd "%CD%"
CD /D "%~dp0"
:--------------------------------------

echo Ramdisk creation script

title Ramdisk Creation

set /p drive_letter=Enter Drive Letter:

if "%drive_letter%"=="" ( set drive_letter=R )

if exist %drive_letter%: (
echo A disk already exists with the letter %drive_letter%:.
echo Please unmount it before using this script.
)

set /p size=Enter Size: 

imdisk -a -s %size% -m %drive_letter%: -p "/fs:fat32 /q /y"

pause

( Pastebin, Raw, Size: 1.16KB )

To use it, first enter the driver letter that you want to assign to the new ramdisk, and then type in the size of ramdisk you want it to create, for example 512M, or 1G. Make sure you don't pick a number that is close to or above the total amount of ram you have in your system! Imdisk grabs all the RAM it will need for the ramdisk in advance!

EcmaScript Features 10: Set

This week's ES6 feature is the Set. If you know C♯, you'll find the ES6 set to be very similar to C♯'s List class. If not, all will be explained below.

Javascript's Set is essentially a list, with a few differences here and there. You can add things to a set using the .add(thing) function, check whether a Set contains a specific value with the .has(thing) function, and get iterable object full of [key, value] pairs with the .entries() function:

> set = new Set()
Set {}
> set.add("apples")
Set { 'apples' }
> set.add("milk")
Set { 'apples', 'milk' }
> set.add("bronze pineapples")
Set { 'apples', 'milk', 'bronze pineapples' }
> set.has("milk")
true
> set.has("grapefruit")
false
> for(var item of set.entries()) { console.log(item); }
[ 'apples', 'apples' ]
[ 'milk', 'milk' ]
[ 'bronze pineapples', 'bronze pineapples' ]
undefined

Since a Set doesn't really use key value pairs, both the key and the value will be the same, unlike C♯'s List, which uses numbers as the keys for every element inside the List. This leads to an interesting situation. Suppose you try to add two identical things to a list:

> set = new Set()
Set {}
> set.add(1)
Set { 1 }
> set.add(3)
Set { 1, 3 }
> set.add(5)
Set { 1, 3, 5 }
> set.add(5)
Set { 1, 3, 5 }

You would probably expect to see the 5 appear twice in the above example, but it only appears once. What is going on here?

Since the Set uses the values you add to it as the keys when it stores the data for you, it means that if a value you give it is the same as one that you have added before, the key for the new value is the same as the key for the previous value. The result: an iterable object of unique items. You could use the new Set to ensure that your program doesn't have any duplicate entries.

Because the key and the value or any given entry are the same, it means that you have to pass a given entry to the delete function instead of it's index (which it doesn't have) in order to delete it:

> set = new Set()
Set {}
> set.add("piano")
Set { 'piano' }
> set.add("viola")
Set { 'piano', 'viola' }
> set.add("trombone")
Set { 'piano', 'viola', 'trombone' }
> set.delete("viola")
true
> set
Set { 'piano', 'trombone' }

That concludes this post on the ES6: Set. Next time, I will probably take a look at the new strign searching functions and the new number / math related functions.

Art by Mythdael