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

Learning Prolog: Lab Session #3

The new learning prolog banner!

I'm back with the third post in this (rather unexpected) series! I think I might be getting the hang of this. It's rather abstract and difficult to visualise though. Perhaps there's a tool out there that lets you visualise your Prolog programs to better understand them (If you know of one, please leave a comment down below!) This week's lab introduced the idea of rules. A rule in Prolog is basically if this then at. For example, if the temperature is low and there are lots of clouds in the sky, the weather can be considered bad.

Here's an example:

weather(bad) :-
    temperature(low),
    cloud(high),
    visibility(low).

weather(good) :-
    temperature(high),
    cloud(low),
    visibility(high).

weather(unsure).

temperature(low).
cloud(high).
visibility(low).

(Pastebin, Raw)

The last 3 lines of the above describe the weather at the moment - feel free to change them. The :- bit is simply the equivalent of the IF syntax in Prolog (rather odd if you ask me). Anyway, using the above we can now ask Prolog what the weather is like so:

?- weather(What).
What = bad .

Note that you nad to press enter in order to tell Prolog that it got the correct answer. This is because it has detected that there are other possible answers that it hasn't evaluated yet. You can press space to tell Prolog that it hasn't found the correct answer, but more on this later.

The above, in english, says something like this:

The weather is bad if the temperature is low, there's lots of cloud cover and visibility is low. The weather is good if the temperature is high, there aren't many clouds about and visibility is high. If the weather is neither of the above, then we are unsure about whether the weather good or bad.

We can also use rules in Prolog to categorise something based on a set of rules. Here's an example that works out what category a test score would fall into.

grade(distinction, Mark) :-
    Mark >= 70.
grade(pass, Mark) :-
    Mark >= 40,
    Mark < 70.
grade(fail, Mark) :-
    Mark < 40.

(Pastebin, Raw)

Using the above, we can ask Prolog questions like this:

What grade would I get if I got a mark of 86?

What grade would a mark of 52 be?

And so on. Here's how you would ask Prolog the above questions:

?- grade(Category, 87).
Category = distinction .

?- grade(Category, 52).
Category = pass .

?- grade(Category, 11).
Category = fail.

verything was all going rather well, until I got to the final excersize. It was based on getting Prolog to tell you whether a car fault was electrical or not. Here's a description of what we were asked to do:

A car fault is electrical if the car won't start or the lights are broken. A car fault is also electrical if the car won't start and the lights won't work, or the battery is flat.

After some thought, I came up with the following:

car_fault(electrical) :- % colon-if represents IF in Prolog.
    wont_start; % Semi-colons represent OR in Prolog.
    lights_broken. % Full stops terminate rules.
car_fault(electrical) :-
    (wont_start, % Commas represent AND in Prolog.
    lights_broken);
    flat_battery.

wont_start.
lights_broken.

Where you define any combination of wont_start., lights_broken. or flat_battery beneath the rules, depending in your situation. However, I got a nasty error when I tried to run it, complaining that I hadn't defined something. After sone looking into it (and some help from my lecturer), we found that you need to explicitly tell Prolog that it's OK if lights_broken., wont_start., or flat_battery. aren't defined, and that it shouldn't throw an error. You can do this like so:

:- dynamic wont_start/0.
:- dynamic flat_battery/0.
:- dynamic lights_broken/0.

(Full version: Pastebin, Raw)

Then you can ask Prolog whether your car has an electrical fault like so:

?- car_fault(What).
What = electrical .

...and Prolog will reply that yes, it is an electrical fault if the above rules are met. Otherwise, it will reply false. To practice, try extending the above to include the following:

A car fault is mechanical if the windows have been smashed.

A car fault is also mechanical if the engine is smoking, or if the engine is making a loud noise.

Just ask in the comments for the answer to the above, or if you need help. Also note that I can't tell who's reading this blog if you don't comment! I don't have any analytics set up at all.

Update 16th Jan 2016: An anonymous commenter (please leave your name next time!) alerted me to a mistake in the test grading example. I've fixed it now, thank you!

Learning Prolog: Lab Session #2

The new learning prolog banner!

Apparently we are supposed to complete the second and third set of lab instructions before the next lab. This post is about what I've learnt from the second lab session, and my thoughts along the way.

Now that I've played around with Prolog for a bit, I've discovered that it isn't really as bad as I thought it was to start with, although the inbuilt editor is absolutely terrible (and there's no real replacement :/).

Last time I learnt that Prolog is rather like a detective in that you tell it about the world, and it can then answer simple questions based on what it's learnt. It's also capable of working things out that you don't explicitly tell it, for example that cats don't like bones - they like milk instead.

Today's lab session started off with some simple Maths. Prolog, apparently, isn't particularly good at Maths - and I'm inclined to agree. Maths in Prolog is done through the use of the symbol comparison system. For example, you can ask Prolog is 2 is equal to itself:

?- 2 = 2.
true.

Prolog replies that yes, 2 is equal to itself. This is relieving, as something would be very wrong otherwise. You can ask Prolog whether other things are equal to each other:

?- two = two.
true.
?- carrots = carrots.
true.

This is mildly interesting, but not really useful. Let's ask it something a bit harder.

?- 4 = 2 + 2.
false.

Erm right. That's not the answer we were expecting...! The reason for this is that Prolog sees the above in terms of the literal symbols that we gave it. So Prolog sees this instead:

Is four equal to "two plus two"?

The equals operator in Prolog actually means unify (are these things the same?), and Prolog is a bit stupid and takes this more literally than we intended. Thankfully, there's another operator we can use:

?- 4 is 2 + 2.
true.

That's much better. The is operator can be used to check if two things are equal as well, but the difference here is that Prolog will perform any mathematical operations that it comes across on the right hand side. In addition, it can be used to set variables (more on that later). The is operator supports brackets, too, allowing you to do this:

?- 40 is ((2 * 10) / 4) * 8.
true.

Variables

Variables in Prolog always start with a capital letter, and are useful when you want to ask Prolog questions like "What does a cat like?" or "What is purple?". Here's an example knowledge base:

purple(flower).
purple(elephant).
animal(elephant).
animal(cat).

Given the above information, we know we can ask Prolog questions like these:

?- purple(elephant).
true.
?- purple(cat).
false.

Those are nice, but rather obvious. Let's step it up a bit, and ask it what is purple:

?- purple(What).
What = flower .

Note that you have to hit enter after entering the command to confirm that the answer is correct. In the above it has correctly identified that a flower is purple and put this information into the variable What. Let's see if we can retrieve the contents of the variable later on:

?- What.
% ... 1,000,000 ............ 10,000,000 years later
% 
%       >> 42 << (last release gives the question)

What's going on here?! This is certainly a rather odd response. The problem here is that variables in Prolog are scoped to the command that's executing. This seems rather useless for now, but at least we use them to ask Prolog a different sort of question. This also works with multiple predicate parameters:

food(cheese, dairy).
food(milk, dairy).
food(cabbage, vegetable).
food(orange, fruit).

Given the above knowledge, we ask things like:

?- food(What, vegetable).
What = cabbage.
?- food(What, dairy).
What = cheese .

Prolog correctly identifies that a cabbage is a vegetable, and that cheese is a dairy product. Note that it picked cheese over milk, as cheese is the first thing it came across. I have a feeling this might be important later on.

That concludes this post on Prolog. If you found it useful, please comment below! I don't run any sort of analytics on here at the moment, so I can't who's reading (or not). If you found a mistake (which is likely) or just want to say hello, please also leave a comment below.

New Sharing Buttons! (and how to get your own)

The other day I was asked by someone to add some share buttons to my blog. After taking a little look into it, I found that it really wasn't that difficult to do. Now you'll find three share buttons at the bottom of each post. To start with I picked Twitter, Facebook and Evernote, but if you would like to see any other services just leave a comment down below.

The new sharing buttons are surprisingly simple. All they are is an image wrapped in a specially constructed hyperlink:

https://twitter.com/share?url=<url>&text=<text>&via=<via>
https://facebook.com/sharer/sharer.php?u=<url>
http://www.addtoany.com/add_to/evernote?linkurl=<url>

Simply replace <url> with your url, <text> with your text, and <via> with your twitter handle (without the @ sign). Don't forget to run everything through rawurlencode() though, otherwise some special character might sneak through and break the link.

Dividing by zero doesn't always throw an exception

Yesterday I had my first Advenced Programming lab session. Part of the instructions get you to investigate how small a number has to be in order to throw a division by zero exception. I discovered, however, that if you use a double, it does not, in fact, throw any such error. I did some investigation, and thought I might share what I learnt here.

According to Google, C++ only throws a division by zero error if it is doing integer math. It doesn't seem to care if it is doing floating point math. This is because floating point numbers can hold the value Infinity, and integers can't. This means that none of the following statements will throw an error:

double x = 10.0 / 0.0;
float y = 371 / 0.0;
int z = 89.0 / 0.0;

The last line of the above looks like it should throw an error, but it doesn't. The reason for this is that it calculates 89.0 / 0.0 using floating point maths to be Inf, and then converts that into an integer. Since Inf doesn't convert directly, it picks the next best thing I'd assume. The following, however, will all throw an error:

int x = 10 / 0;
float y = 1000 / 0;
double z = 4560 / 0;

Prolog: First Impressions (or a basic tutorial on the first lab session)

The new learning prolog banner!

Yesterday I had my first artificial intelligence lab session on Prolog. It didn't start off very well. The instructions we were given didn't seem to have been tested and were largely useless. Thankfully one of the demonstrators came over to help and showed me the basics.

This blog post is part review, part first impressions, and part tutorial. It's purpose is to consolidate the things that I have learnt. Hopefully it will be useful to someone else out there :) Also note, if you haven't figured it out by now, I am a complete beginner with Prolog. There will be mistakes! If you spot one, please comment below so that I can fix it :)

My first impression of Prolog is that it is hard. It is very hard to learn. This isn't helped by the fact that the tools available to the new Prolog programmer are very out of date and feel exceptionally clunky. Perhaps a redesign is in order?

Anyway, I discovered at first that Prolog is very much like a detective. You give it facts and relationships, and then question it on the information you've given it (much like comprehension) using things called queries. Here's an example of a fact:

cat.

In the above, we are telling prolog that something called a cat exists. In it's world now, a cat is the only thing in existence. We can then ask it whether a cat exists in the world in the query window by running the prolog file. If you are using the default editor that comes with Prolog, simply press CTRL+C and then CTRL+B. If you aren't, type prolog filename.pl to launch a query window based on filename.

?- cat.
true.

Prolog is telling us that a cat exists, but we knew that already. Let's try asking it whether a dog exists:

?- dog.
ERROR: toplevel: Undefined procedure: dog/0 (DWIM could not correct goal)

Oh dear! We get a nasty (over)complicated error! Thankfully, this error (in this case) is a really simple one. Prolog is basically telling us that it doesn't know what a dog is, because a dog doesn't exist in Prolog's world at the moment.

Getting Prolog to tell us whether something exists in it's world is nice, but it isn't terribly useful. Let's try something a little bit more complicated.

animal(cat).

The above tells prolog that a cat is an animal. For reference, the bit before the opening bracket is called a predicate I think. After executing the above, Prolog's world jsut got a bit more complicated. It now knows that there is something called a cat, and that a cat is an animal. We can then ask Prolog if a cat is an animal like so:

?- animal(cat).
true.

Prolog tells us that yes, a cat is an animal. This is also nice, but still not amazingly clever. Let's write some more Prolog.

animal(cat).
animal(dog).
animal(cow).

pet(cat).
pet(dog).

food(milk).
food(bone).

likes(cat, milk).
likes(dog, bone).

The above looks much more complicated, but it's not as bad you might first think. In the above, we tell Prolog that a cat, a dog, and a cow are animals. We also tell it that only a cat and dog are pets. In addition, we say that both milk and a bone are forms of food, and that a cat likes milk, and a dog likes a bone. We can then ask Prolog a bunch of questions on the above:

?- animal(cow).
true.
?- pet(cow).
false.
?- likes(cat, milk).
true.
?- likes(cat, bone).
false.

In the above, we ask prolog 4 questions:

  1. Is a cow an animal? Prolog answers that yes, a cow is in fact an animal (we told it so).
  2. Is a cow a pet? Prolog answers that no, a cow isn't a pet. It knows that because we told it that a cow is an animal, but we didn't tell it that a cow is a pet.
  3. Does a cat like milk? Prolog answers that yes, cats do like milk - because we told it so.
  4. Does a cat like a bone? Prolog answers that no, cats don't like bones, as we told it that cats like milk instead.

Prolog is starting to show how powerful it is, but I have a feeling that I haven't even scratched the surfaced yet. Next week, assuming I understand the next lab, I'll make another post about what I've learnt.

My thoughts on SVN (or how to use git-svn to avoid it)

My university uses SVN as their preferred source code control system, and I came into contact with it for the first time the other day. For one of the modules I'm taking this year all the lab work is located in a special SVN repository. The ACW (assessed coursework) also has to be submitted through this SVN repository.

I found that (after some simple mistakes) it's not particularly difficult to pull down a repository - just a little bit fiddly (you have to create the directory to clone a repository into first). The trouble started when I tried to commit my changes. I found it almost impossible to just do a simple commit that contains all of the changes I'd made so far, though I might be missing something.

SVN itself feels rather clunky and outdated in the way it works. It doesn't have an inbuilt fork system, and you can't commit if you are offline (or if the central master repository is offline). Git, by comparison, supports both of these things. In addition, git apparently has better support for branching and merging, though I haven't come into contact with it yet.

My solution for this for now it to use git-svn. To check if you have it installed, simply run the command git svn --help. If it's installed, you will get a help message. If not, you'll get a harmless error message. On Linux you can install it via sudo apt-get install git-svn. On Windows you should have it installed by default.

With git-svn, you can clone an SVN repository much like you would for a regular git repository: git svn clone https://path/to/svn/repo. This clones a remote SVN repository down into a local git repository.

From here you can do any number of git commits as normal. When you are ready to push your changes back up to the remote SVN repository, simply run git svn dcommit. This will push all of your git commits up to the remote SVN repository as revisions.

Hopefully this post is helpful to someone. If I'm missing something here (and I probably am) please leave a comment below!

Update: If you need to pull down remote changes from the server, simply run `git svn rebase.

A Script to update Node.js to the latest version

As you may be aware, io.js and Node.js have merged into one project once again. While this is good news for the community, it also means that those of us using a bash script to update io.js to the latest version (like myself) need to find another method to stay up to date.

I found nvm, but I found it really didn't work with my current setup on my server. I took a look at the iojs-update script I found online that I've been using, and I found that it wasn't too tough to reconfigure for Node.js. Now that it's working, I thought that I'd post here so that you can use it too. I'm using it with Ubuntu 15.04, but it should work with any Debian based system.

I've forgotton the original author's name, but if you post in the comments, I'll credit you appropriately in this post.

Here's a link to the gist: https://gist.github.com/sbrl/48e6423f2e97462149ef

If you just want to download and run it, here's a command to download it to your ~/bin folder and execute it:

cd ~/bin && curl -OL https://gist.github.com/sbrl/48e6423f2e97462149ef/raw/9bf780f8685634dbaae6e0a229d2ad551f3323ed/node-update && chmod +x node-update && sudo ./node-update

If someone knows of an up to date ppa, I'll gladly use that instead.

I hope this helps someone out!

Adding to the $PATH when sudoing

Normally to add to your $PATH permenantly you do something like this: export PATH=$PATH:/new/dir. You may notice though tht this doesn't always seem to work. Here's an example:

$ export PATH=$PATH:/home/sbrl/bin
$ newcommand # works
$ sudo bash
# newcommand # works
# exit
$ sudo newcommand # doesn't work...wait what?

When a command is run with sudo, it doesn't respect your existing $PATH variable. To change it, you need to open the file /etc/sudoers and add your path to the line that says something like

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
:/bin"

In order for your folder to be in your $PATH when you use sudo command.

UFW and Samba

Today I have another post for you about Samba. Today I found that people couldn't actually access the samba shares I set up (I must have forgotten to test them). They were getting a weird "The Network Path was not found" error. Strange. After looking into it, I found that I didn't unblock the right ports in ufw. You see, Samba operates using two listeners, one called smbd, and the another called nmbd. I had forgotten to read the output of netstat -peanut correctly, and I missed a few ports.

For future reference (and for others having the same problem), here's the list of commands you need to enter in order to use shared folders with Samba correctly:

sudo ufw allow 139/tcp
sudo ufw allow 445/tcp
sudo ufw allow 137/udp
sudo ufw allow 138/udp

Hopefully it doesn't take you as long to fix your problem as it did mine...!

Custom Brightness Controller for Ubuntu

While I love Ubuntu's desktop, the brightness and volume controls are rather annoying as they don't provide a great degree of control. To fix this, I wrote a bash script to control the brightness. Here's what I came up with:

#!/usr/bin/env bash
increment=10
backlight_prefix=/sys/class/backlight/intel_backlight/

echo $1
if [[ "$1" = "decrease" ]]; then
    echo decreasing
    increment=$(expr -${increment})
fi

cur_brightness=$(cat ${backlight_prefix}brightness)
max_brightness=$(cat ${backlight_prefix}max_brightness)

new_brightness=$(expr ${cur_brightness} + ${increment})

# Permissions changes on brightness: 
## change group to sbrl
## add g+w
# Old command:
#gksudo -- bash -c "echo ${new_brightness} >${backlight_prefix}brightness"
echo ${new_brightness} >${backlight_prefix}brightness

####################
### Notification ###
####################
### uncomment the following line to disable the notification
#exit
# Calculate the percentage
new_percent=$(echo "(${new_brightness} / ${max_brightness}) * 100" | bc -l)
new_percent=$(printf "%.1f" "${new_percent}")

echo new_percent: $new_percent

max_bar_length=100
bar_length=$(echo "(${new_percent} / 100) * ${max_bar_length}" | bc -l)
bar_length=$(printf "%.0f" "${bar_length}")

n_bar=$(head -c $bar_length < /dev/zero | tr '\0' '=')

# Kill the previous notification
killall notify-osd
notify-send "Brightness: ${new_percent}%" "${n_bar} (${new_brightness})"
#notify-send "Brightness" "${new_percent}%"

(Pastebin, Raw)

To use the above, you need to do several things. Firstly, you need to find your screen's brightness settings. Open a terminal, and navigate to /sys/class/backlight, and find your backlight's folder. Mine is intel_backlight, but yours might acpi_video0. Once found, you should have a file called brightness inside it. Change the value of the backlight_prefix variable on line #3 to equal the path to this folder, not forgetting the trailing slash.

You then need to alter the permissions on the brightness file in order to allow your user account to change it - otherwise you will get prompted for your password every time you change your brightness! To do this, open a terminal and navigate to the folder we found earlier that contains the brightness file. Change the user group to be your username with sudo chgrp username brightness, and then allow write access to group members with sudo chmod g+w brightness. If this doesn't persist across reboots, you might need to add these commands to your rc.local or Xsession files.

It should work now. If you don't want the notification to show every time you change your brightness (or if it doesn't actually work), uncomment line #27.

Art by Mythdael