A must-see lecture on how you should live your life

I must admit, the past week had been very difficult and I was deeply upset by a chain of events that I cannot comprehend at the time. The following lecture allowed me to see the reasons behind those events and have changed my view on the situation entirely, and also life in general, for the better.

The lecture was given by professor Randy Pausch in September 2007 (after he had been diagnosed with terminal cancer) and is titled "Really Achieving Your Childhood Dreams.". In the lecture, he talks about his own life and his life philosophies, and is deeply meaningful and very positive.

Please spend some time watching the video and looking at the slides – I’m sure you’ll find something really positive from it.

Advertisements

Unsure messages

I don’t usually write about personal stuff on here but recent events has taught me to never forget a very important rule – if you are not sure about saying something, don’t say it – no exceptions.

The last 2 words "no exceptions" are very important; the last time this happened, I managed to refrain from pressing the "send" button and I was glad I did that. This time round, I let one such message slip through and it made a simple situation really complicated, and may have far-reaching and tremendous consequences because of this.

So please, for everyone who is reading this, if you can’t refrain from writing that email, at least save whatever you’re planning to send until the next morning. Think about it, think some more, and delete / archive it – but never send it.

BSG Toaster

BSG Toaster

Lol, this just cracked me up when I saw it.

It is actually availiable for sale at the NBC Universial store!

Returning an array from a Bash function

For those of you who are still learning Bash (including me…), I’m sure one of the things you would have asked yourself is "How on earth do I return an array from a bash function?".

Well I’ve written a small script that will explain this:

(Please see update below)

#!/bin/bash
IFS=$'nt'

function fnGo () {
	array=(
		a	s	d	f	
		"gh ij"	"kl mn"
	)
	echo "${array[*]}"
}

# -------- out - String variable --------
out=$(fnGo)
echo ""out" isn't an array: ${out[1]} - nothing"

echo $'n'""out" Works with iteration:"
for item in $out; do
	echo "item:"$'t'"$item"
done

# -------- out2 - An array --------
out2=($(fnGo))
echo $'n'""out2" now an array:"
for ((i=0; i<${#out2[*]}; i++)); do
	echo "item $i:"$'t'"${out2[i]}"
done

echo $'n'"Though "out2" cannot be iterated anymore...:"
for item in $out2; do
	echo "item:"$'t'"$item"
done


Basically, it’s exactly as you’d do for returning a single value from a function (use echo) – but, you need to make sure you surround the variable with quotes (in the function – echo "${array[*]}"), and receive it as an array – out2=($(fnGo)).


Note you can only either choose to use an iterator method (out1), or an addressing method (out2), but not both – run the script and you’ll see what I mean.

Oh, one more thing (just as a tip for those who don’t already know) – pay attention to your IFS variable (which determines how parameters are separated)! This is especially important if you’re taking in quoted (escaped) command-line parameters that may have a space in them (such as file names) – in that case, I normally use "n".

—- Update (2009-10-03 @ 10:35:27) —-

Ok, having written bash scripts for a little while now, I have found a better way of doing this by using a special "return" variable; the old method will not let you actually echo anything onto the console and do things like "exit 1", but the following will:

#!/bin/bash
IFS=$'nt'

rtr=""

function fnGo () {
	local array=()	# You can use array="" - it won't make any difference
	echo "fnGo() called"
	array=(
		a	s	d	f	
		"gh ij"	"kl mn"
	)
	rtr=(${array[@]})
}

# -------- out - String variable --------
fnGo
out="${rtr[*]}"
echo ""out" isn't an array: "'${out[1]}'"="${out[1]}" - nothing"

echo $'n'""out" Works with iteration:"
for item in $out; do
	echo "item:"$'t'"$item"
done

echo -e "n"

# -------- out2 - An array --------
fnGo
out2=(${rtr[@]})
echo -e ""out2" now an array:"
for ((i=0; i<${#out2[@]}; i++)); do
	echo "item $i:"$'t'"${out2[i]}"
done

echo $'n'"Though "out2" cannot be iterated anymore...:"
for item in $out2; do
	echo "item:"$'t'"$item"
done

You may also want to check out this article for the difference in the use of the [*] and [@] for enumeration.

MPlayer resume script (v2-alpha)

MPlayer logo

A while back I attempted to write a wrapper script for mplayer to resume a file. Unfortunately, that script was rather limiting where:

  • File name must be first entry
  • You have to manually specify the "-profile" parameter
  • You cannot specify a global profile (i.e. the profile you specify only applies to the last file)

Now I have a new script that resolves the above issues! Unfortunately, there are some new issues with the new script:

  • It’s slow at generating command for many files
  • Extension-less file won’t work…
  • Per-file manual profile definition is not yet implemented – though automatic RegExp profile definition is working :-P !
  • This script is very much in the alpha stage and more testing is needed – so use at your own risk!

Sounds cryptic? It’ll be clearer after I’ve shown you some examples.

As with the previous script, an example usage (we’ll assume we’re trying to resume a file called "mediaFile.avi" at timecode 300, and the script is named "mp"):

echo 300 > mediaFile.avi.txt
mp mediaFile.avi

Also as with the previous script, you’ll probably want to enable the "statusline" display by adding "msglevel=statusline=9" into your mplayer config file (at "~/.mplayer/config" | "/etc/mplayer/config"), and ensure "quiet=0".

Now, to use a profile for all files (at the moment, it doesn’t matter where you place "-profile" and "-ss" – they just get applied to every file…):

mp -profile hd file1.avi "file 2.avi"

However, the real magic of the v2 script comes into play when you have multiple files, matching multiple profile switching definitions, with different resume files! For example:

$ ls -d *.avi*
file1.mts
file1.mts.txt
2x03 SomeEpisode.mkv
2x03 SomeEpisode.mkv.txt
file2.avi

$ less mp
...
profiles=(
	# [PF name]	[RegExp]
	"hd"	"(/|^)[0-9]{,2}x[0-9]{,2} .*.mkv$"
	# ---- Generic profiles ----
	".mts"	".mts$"
)
...

$ mp file1.mts "2x03 SomeEpisode.mkv" file2.avi

The script will now use the ".mts" profile for the mts file, the "hd" profile for the .mkv file, the "global" profile for the .avi file, whilst picking the values out of the resume files and resume at the point specified in the .txt files!
(Just in case you’re wondering, the "global" profile is defined in the "$defaultProfile" variable in script.)

Anyway, you can get the script here.

Of course, if anyone’s interested in improving it, they’re more than welcome to do so! Just don’t forget to email me a copy!