Sensible email programs or webapps does not show linked images in emails, since it would be so easy for a spammer to automatically check whether your email address is being read. To illustrate this, a spammer could send out an email with an image that pointed to a unique URL. This URL is bound to your email address and if it ever were to be loaded, they would know for sure that your email address was in use.
We also know there are good reasons to show linked images, for instance from a shop you have subscribed to that has some good deals every week. However, GMail gives me the option of always showing images from a certain email address. Do not trust this feature!
Let's say you've subscribed to newegg.com and they send out weekly offers from offers@newegg.com. All a spammer has to do is send out an email to loads of people, forge their address as offers@newegg.com and your email service (GMail isn't alone) will display the picture. The spammer of course links to images on their own server and records your email address as active. However they would also know you're a newegg.com subscriber!
What should have been done is accepting images from a certain domain, as in "Allow images from newegg.com?". That I could trust.
However, the script was blocking all scripts which did not originate from the page you were visiting. This mean that inline youtube videos, google maps and such nice addons didn't work. It didn't take long until I didn't use the script myself. Again I had to live with slow pages...
So I got tired of it again and modified the script. This time, I use a blacklist. Of course this means I have to update the blacklist, but at least this time I won't get broken sites unless I tell the script to do so.
The blacklist is currently very short and I've only used it for a few hours, but it seems to be working nicely so I'm releaseing it. Install the script, read the previous post if you don't know how, and if you'd like to help out you could gather more links to put in the blacklist.
Many ads are added by just linking an external script to the page. I'm going to show you how to stop all scripts that are not originating from the domain you are currently visiting.
Copy the code below, save it to a file 'prevent_all_external_scripts.js' and add it to a folder. I call my folder 'userjs' and is placed in my documents.
window.opera.rx295723629 = new RegExp('^http:\/\/([a-zA-Z0-9\u0080-\u00ff-.]*)?'+location.hostname);
window.opera.addEventListener(
'BeforeExternalScript',
function (e) {
var src = e.element.getAttribute('src');
if(src.match(/^http:\/\//) && !src.match(window.opera.rx295723629)){
opera.postError('Script outside '+location.hostname+' was found and blocked: '+src);
e.preventDefault();
}
},
false
);
Open Tools->Preferences->Content->Javascript Options and add the folder to the text box at the bottom, where it says "User Javascript Files".
Now any site you are visiting will load scripts originating from the current domain, but ignore external scripts.
I have a bad habit of closing Opera when it has opened more than 50 tabs. Needless to say, Opera could take a while to open the next time, even if I just wanted to see a single page very quickly.
So I created a batch file to make a backup of autosave.win.
Create a "session backup.bat" file and put the following code in it:
for /f "tokens=1-5 delims=:" %%d in ("%time%") do copy "autosave.win" "autosaved %date% %%d-%%e-%%f.win"
Place the batch file in the sessions folder (Open the menu item Help->About Opera and open the path that says "Saved sessions") and create a shortcut to the start menu or your desktop. Whenever you run the batch file, "autosave.win" will be copied and have added a timestamp to it.
I just started playing around with Ruby, and it is an awesome language. It does have its cons, as do all tools, but the ease of scripting is very... I don't know, relaxing :-). My point being that Ruby is easy to learn. I've only used Ruby for what is approximately a full work day, but I'm already in love Ruby offers you close to the power of a real language, but the ease of a scripting language. You get full access to the platform, like calling COM objects in IE or Office - so you should be able to read Excel sheets if you are running Windows and have Office installed.
So, getting to the point of this blog post. The assumption is that you have written a lot of methods, your own little library. Developers are running uphill to meet the requirements of management and there is no time to look at efficiency. At the end of the development cycle, developers are noticing the application is running slower than users would expect, so it is time to look at efficiency.
Let us assume you only have two functions, count(number) and subtract(number). The functions will count from 0 to 'number' and from 'number' to 0 respectively. Yay, how very useful...
def count number
number.times do
number += 1
end
end
def subtract number
number.times do
number -= 1
end
end
Ruby supports aliasing methods. This is the same as copying a method. In Javascript, you would do
somefunction = someotherfunction;. This method of performance testing can be done in any language that supports modifying or copying a method to another name. Let's alias our methods now, and add a global variable we'll keep some records in.
alias countOriginal count
alias subtractOriginal subtract
$gRec = []# store the function running time in here
All the previous running code will still call count and subtract, so there is no difference to the apparent program flow. But now we can redefine how count and subtract work!
defcount number
start = Time.now # store the start time
countOriginal number # call the original function
stop = Time.now # store the end time# We should have very little overhead timing
# above and after the original function$gRec.push ['count '+number.to_s, stop-start] # store time as seconds end# Do the same heredefsubtract number
start = Time.now
subtractOriginal number
stop = Time.now
$gRec.push ['subtract '+number.to_s, stop-start]
end
Add this in a debug file and the methods you have redefined will now register the time they took in a global variable. I am not sure how Ruby handles array sizing though, so remember that resizing arrays can lead to some relative heavy overhead.
If your code is just slighly complex the timing will probably be wrong unless you specify an array of a certain size at the start. It is enough that foo() is calling bar(), and both functions are redefined. If the array must be resized when boo() is running, it will look like foo() took longer time to complete that it actually would have. This will give you statistical errors.
# Run the code and print out the timer results at the end
count(10000)
count(100000)
count(1000000)
subtract(10000)
subtract(100000)
subtract(1000000)
puts $gRec.inspect
This gives you the following output: [["count 10000", 0.0], ["count 100000", 0.047], ["count 1000000", 0.484], ["subtract 10000", 0.016], ["subtract 100000", 0.031], ["subtract 1000000", 0.469]]
Google supports several cool features. One is searching a specific site or even a topdomain. By typing "sennheiser px 100 site:no" you can search for Sennheiser PX 100 only for norwegian sites. (And by the way, Sennheiser PX 100 and MPX 100 are awesome!) But what if you want a specific "search only norwegian domains" added to Opera? I'll show you how . Go to Google and create a search.
Expand details in the dialog and look at the search query. Servers will separate all the values by the "and" sign (&). For Google, the interesting part is the 'q' value. I've highlighted the interesting part in the image.
When you select an input and choose "Create Search", Opera does some light processing and finds which part you want to be variable. For the variable, Opera puts "%s" and will insert what you want to search for where the "%s" is. Everything else is left alone, which means that you can insert more text if you want! So instead of it saying "q=%s", you can change it to say "q=%s site:no". Give the new search a keyword, such as "gn" (for google norway) and click "Ok". Now you're done, and the newly created search will always add " site:no" to any search query you're making!
Operators behave mostly the same in many different languages, but in some you can use some nice tricks to save some space. For instance, in ecmascript you can assign a variable value from a deep tree without the risk of the script aborting because the array value was undefined.
var foo = c && c[0] && c[0][1];
The code will assign foo the value of c[0][1] or unassigned. The equivalent of this code is
var foo;
if(c)
if(c[0])
if(c[0][1])
foo = c[0][1];
Boolean operators are conditional if you use && or ||. Using the AND operator, the following statements will not be executed if the current is false. Using OR, the same is true if the current is true. Here is an example using conditional OR
var foo = (bar < 10) || 5; // assigns 5 or true
You can use conditional operators as a shorthand of if. The last evaluated statement is the returned value.
Assignation
The assignation operator, =, does in fact return a value and is not always true. The assignation operator returns the value that was assigned, so foo=10 returns 10. This is the basis of how this effective loop works:
for(var n=0,e;e=array[n];n++){}
As long as the array contains values that are not evaluated as false in a boolean context, such as 0, '', false and probably a few others, it works fine. The reason is that the loop continues as long as the middle statement is true, and the returned statement is array[n].
I've heard from several sources, on the web that is, that you should stay away from recursion if you need someone else to maintain your code. The argument is that recursion is hard and some people just don't understand it. Well boo hoo. Start understand it or maintain some easier code. I mean, we covered recursions during the first year of uni! (I might be easier to deal with and agree to stay away from recursions if you're paying me lotsah' monies , but I'm happy where I am right now.)
Generate a thought map in your head. Divide problems into smaller ones and then conquer them. Let's have a look at scanning a tree. We want to see if a tree contains the number 42.
We know for certain we have to look at the root node if it contains the number 42. If it does, we return true and everyone is happy. If not, we should start looking at child nodes. For every child node, we should see if it contains the number 42. It it does, we return true and everyone is happy. If not, we should start looking at child nodes.
Hang on now! During my thought map above, I just repeated the exact same thought sequence. It is as if *gasp* it is a loop!
It is.
The function is just calling itself just as how it would call any other function. I think the word just scares people. Of course, recursions are more prone to infinite loops compared to calling other functions, but for loops are also more prone to infinity than copy&pasting a lot of code! You just have to know how to use the tool.
Here's the code to scan a tree where every node has an int value and an array children.
// scan a node and it's children
function scan(node){
if(node.value==42){
return true; // Everyone is happy
} else {
// Look at child nodes
for(var i=0,child; child=node.children[ i]; i++){
// scan a node and it's children
if(scan(child))return true;
}
}
}
This should demonstrate it is not specifically hard writing recursions. I wrote the above code and it worked the first time I tested it [1]. There is no alterations in the above code after I tested it the first time. I did forget to add return false after the for construct, but looking at the mental spec above, there is no mention of returning false at any point ;-) And besides, undefined is evaluated as false in a boolean context.
Some crazy people are advertising that I can look up names and numbers for peoples phone numbers by sending an SMS message. It only cost 50 cents (3,- NOK), hurray for them! Or ah, em... it costs 50 cents for every suggestion they send you. Which is often wrong so it usually cost a dollar.
Wouldn't it be sooo great to have an entire phonebook on your cellphone? Just enter the name, phone number or address and you can view an entire list of suggestions. It'd be fantastic if it even was cheap! Let's say 1 cent, or therearound! Man, this sounds like a fantastic deal! Serve it up, dude!
I will comply thy wishes.
Install Opera Mini and surf the net. The norwegian phonebook is available online at Telefonkatalogen.no. Just use whichever is available where you live.
If you want to create a search engine, edit the search field and go to options. There is a choice that says "Create Search...". Congratulations, the service is now easily available on the front page of Opera Mini.
I was in a hospital a while back and decided I wanted to order a limitless 3G internet connection. I heard Ice offered one for an acceptable price, but since I was locked to the hospital bed, I had to visit their page using Opera Mini. It looked pretty much like this:
Using randomness to ensure row uniqueness is a bad solution. Since I only started working a few months ago, my only experience with peers had been with fellow students. I remember several WTF stories from college, such as when one of the groups spent a full day writing their own full-text search instead of using the LIKE %search_string%. Maybe we should just be glad he didn't build his own processor first However, messing up like this is accepted and also useful while in college. I bet he learned a lot during that day.
On the other hand, I was talking to a developer at work and was surprised by how many previous colleagues he had known that never read the manual. If you do not read the manual, how do you know the function you are calling do what you are guessing it will do? I guess you don't because you are just copy and pasting, huh?
If you ever are writing code for something important you should always read the manual. If you do not read the manual, a nasty bug will happen and it will bite hard. Because the bug had been easy to understand if you just had read the manual, this flaw will reflect very badly on you.
I usually listen to Slay Radio while at work. I grew up with a lot of the music they play, which is a lot of gaming and modding music. You can find most of the tracks they play on Remix64. Go there and add the search field as an engine - if you're using Opera. Of course you are using Opera while reading this blog, right?
I bought a Playstation 3 a few weeks ago and tried to let it crunch some numbers at Folding@Home. It is amazingly fast! If you still haven't thought about it, you should try to donate some time from the playstation to help science find new medicines.
If you are thinking about how this could waste power and such, fear not if you live in a cold country like me. The first law of thermodynamics states that every single joule of power will eventually heat up your apartment. It's only waste during summer
How does our brain work? Do you really think it is bug free? Ramachandran speaks about how our brain works and fails. We look at how our brain fails because this is the best tool we have of understanding ourselves.
LittleBigPlanet on first glance seems so much like a cuddly game for 3-year olds. You control a cute puppet through a puzzle platform. If I had stopped describing the game here, you would have browsed somewhere else and forgot about it. But read on!
You can invite friends into the game and play cooperatively. Solve puzzles by standing on each others shoulders to be taller, lift friends up to where you are. Stand on a springboard and at the top you fling your friend upwards so he can reach a string which he toss down to you.
The game is fully physics based, so most all puzzles you encounter will base themselves on interacting with the environment. Turn a hedgewheel here, grab on and be lifted to the top. Grab onto a string and pull down a wooden board it is connected to so you can walk up your newly created stair.
But there is so much more. You can also create objects! This will be necessary to complete some tasks, but you can also create an entire level if you want. Share the level online and let others try it out too.
You can control the puppets arms with the left and right analog stick. The puppets mouths are supposedly lip synched to what you are saying through the headset!
You know what... Just watch the video, it will show you a lot of what the game is about.
This is a great talk by Michael Shermer, the founder of the Skeptic Society, of why we believe strange things.
Why do people see the Virgin Mary on cheese sandwiches or hear demonic lyrics in "Stairway to Heaven"? Using video, images and music, professional skeptic Michael Shermer explores these and other phenomena, including UFOs and alien sightings. He offers cognitive context: In the absence of sound science, incomplete information can combine with the power of suggestion (helping us hear those Satanic lyrics in Led Zeppelin). In fact, he says, humans tend to convince ourselves to believe: We overvalue the "hits" that support our beliefs, and discount the more numerous "misses."
And finally Linux has *everything* I need for my laptop. Ubuntu Gutsy Gibbon fixed my two main peeves, and patched every sore issue up with another very nice feature, 3D effects.
Hardware
The laptop I use is an HP: Compaq nx6325. It's a business laptop and come in two variations. The one I have has a screen resolution of 1400x1050. Ubuntu works very well on this laptop! However to make 3D effects work, you need to enable restricted drivers for the ATI card and install xserver-xgl. Just open Synaptic package manager and search for it. Oh, and add compizconfig-settings-manager while you are at it. I only wish I didn't have to search on Google to find how to enable 3D effects, but I blame it on bad drivers. Hopefully, someone will create some open drivers for ATI cards soon.
Issue 1: WiFi drivers
I couldn't use my wifi card, so I had to rely on a cabled internet connection. I still figured that Ubuntu was worth using despite this maddingly lacking feature. I could probably have tried to install ndiswrapper and done it myself, but I didn't want to muck around with this once more. The last time I tried it, I had to reinstall a while later because I made such a mess.
Status: Fixed (and also bluetooth works well!)
Issue 3: NTFS
Not really a problem with Linux in and of itself, but when Windows is in such a powerful position it does bring some problems if you can't read the filesystem it use. I have windows installed on my gaming computer and my external harddrives usually are formatted with NTFS. So usually I couldn't write to these external disks using Ubuntu.
Status: Fixed! Read AND write is now enabled by default in Ubuntu.
Cool new feature: 3D desktop
Having a desktop enabled with 3D effects are cool but not really useful by itself. However, dig a bit deeper and you will find features enabled to make your life easier! I especially like the "Scale" effect. You press Shift+Win Key+Up to enable it and all the windows are zoomed out so you can see every window on the desktop live! This is how Alt+Tab should really be! You can then point using the arrow keys or click on the window you want with the mouse to enable it.
Another cool feature is that you can unfold desktops. For the uninvited, Ubuntu (and other window managers on linux) offers you several desktops of which you can manage your windows. It is like having several desks where you could put all papers that are relevant of each other. When you "unfold" by pressing Ctrl+Alt+Down, all desktops will zoom out and you can see three of them on lined up on the screen. Just flip through them pressing left and right until you see which one you like and release Ctrl+Alt.