Wednesday, October 28, 2009

Displaying and Configuring Character Sets in MySQL

Display all character sets:

show variables like 'character_set%';

Change the character set for a table:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

BUT with the caveat that
The CONVERT TO operation converts column values between the character sets. This is not what you want if you have a column in one character set (like latin1) but the stored values actually use some other, incompatible character set (like utf8). In this case, you have to do the following for each such column:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;

The reason this works is that there is no conversion when you convert to or from BLOB columns.

The process to completely change all mysql's character sets from latin-1 and make this garbage:
(using the show variables command from above)
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
look beautiful like this:
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
involves simply adding the following to the [mysqld] section of your my.cnf (or /etc/mysql/my.cnf if you like, and are on a debian based machine)

collation_server=utf8_unicode_ci
character_set_server=utf8

and adding the following to BOTH the [client] section AND the [mysqld] section:

default-character-set=utf8


This is simply in case you cannot go back and re-compile mysql using
./configure --with-charset=utf8 --with-collation=utf8_general_ci

Tuesday, October 27, 2009

Completely removing gnome from ubuntu.

I use terminal only versions of ubuntu on several vm's that I have set up. Maybe I should use something else, like just plain debian with no gui, but either way I was looking for a way to completely remove all gnome elements from my virtual machines. In the end I found a LONG command that just lists all the gnome elements to send to the apt-get remove command... seems like there should be something more elegant...

The commands are here, but it needs to be noted to remove the `&& sudo apt-get install kubuntu-desktop` from the end of the commands.

Sunday, October 18, 2009

Well.. so much for javascript..

I have always despised javascript and html for it's hacky approach to...well.. everything. Html was well done in the 90's, maybe, but at the moment html and javascript just look and feel and appear to work like one huge cobbled together kludge that nobody can fix because the entire world uses html/javascript and sorta knows how it all fits together. Years ago when I was the webmaster for a small college, I dealt with javascript/html extensively and hated it intensely (back in the age of ie3 and Netscape and just the beginnings of mozilla 1.0).

So after my latest little adventure in javascript and getting everything to work perfectly in FF3, my girlfriend, who does QA for another web company, asked 'Does it work in Internet Explorer?' So I tried my simple little <input> hider (along with all the concessions I made for I.E) in I.E 8. I was expecting that there might be some small issues that would popup, but nothing major. Instead what I got was I.E 8 completely freezing to the point where I couldn't even kill it in the task manager. I got the Vista little spinning ring of death and in order to fix the issue, I had to get to the ctrl-alt-delete menu and hit 'logout'.

Now I know that there's lots of people out there who are experts in making javascript things in sing in both ie8 and ff3, but at what cost? I work at a company who primarily works with flash and there's always a big discussion/name-calling-fest whenever a site is made entirely in flash when it 'should' be made in html/javascript. The main reason people usually defend the decision to use flash is something along the lines of "we have lots of very good flash developers and it's faster for them to just develop the site in flash", which is true. The 'it works properly in all browsers with a minimum of fuss' is rarely even brought up.

But given the amount of design considerations, QA, potental major headaches that have to be taken into account when developing an html/javascript site, I would have to say that these issues are very significant. Developing in flash is significantly easier simply because the majority of these issues are minimized. You simply develope the app, QA it and deploy it. It works as expected in all browsers. No special considerations that need to be learned and tested, no design decisions that have to be abandoned because the feature will work in one browser, but not in another.

Flash wins.

Update: HTML 5 to control them all.

Learning Jquery and rehashing javascript..

Been learning jquery and messing around with hiding things dynamically in the django-admin...


indexOf doesn't work in IE
so basically the work around is to apply it to ie's version of js..

if (!Array.indexOf) {
Array.prototype.indexOf = function (obj, start) {
for (var i = (start || 0); i < this.length; i++) {
if (this[i] == obj) {
return i;
}
}
}
}


There is no string title case function so again, put one in yourself..

// (c)GPL, apv
String.noLC = new Object
({the:1, a:1, an:1, and:1, or:1, but:1, aboard:1,
about:1, above:1, across:1, after:1, against:1,
along:1, amid:1, among:1, around:1, as:1, at:1,
before:1, behind:1, below:1, beneath:1, beside:1,
besides:1, between:1, beyond:1, but:1, by:1, 'for':1,
from:1, 'in':1, inside:1, into:1, like:1, minus:1,
near:1, of:1, off:1, on:1, onto:1, opposite:1,
outside:1, over:1, past:1, per:1, plus:1,
regarding:1, since:1, than:1, through:1, to:1,
toward:1, towards:1, under:1, underneath:1, unlike:1,
until:1, up:1, upon:1, versus:1, via:1, 'with':1,
within:1, without:1});

String.prototype.titleCase = function () {
var parts = this.split(' ');
if ( parts.length == 0 ) return '';

var fixed = new Array();
for ( var i in parts ) {
var fix = '';
if ( String.noLC[parts[i]] )
{
fix = parts[i].toLowerCase();
}
else if ( parts[i].match(/^([A-Z]\.)+$/i) )
{ // will mess up "i.e." and like
fix = parts[i].toUpperCase();
}
else if ( parts[i].match(/^[^aeiouy]+$/i) )
{ // voweless words are almost always acronyms
fix = parts[i].toUpperCase();
}
else
{
fix = parts[i].substr(0,1).toUpperCase() +
parts[i].substr(1,parts[i].length);
}
fixed.push(fix);
}
fixed[0] = fixed[0].substr(0,1).toUpperCase() +
fixed[0].substr(1,fixed[0].length);
return fixed.join(' ');
}
Javascripts objects work as associative arrays
var theStatus = new Object;
theStatus.Home = 'normal';
theStatus['Home'] //will print 'normal'

Arrays are useful as in all languages, but their function set isnt really all that complete and require some inelegant code to remove elements properly. (Mainly just
var arr = [4,5,6];
arr.splice(arr.indexOf(5), 1);
Also, to copy arrays by value, you have to use the splice() fn...

There's no elegant way to copy objects by value, so again.. add it in yourself.
Object.prototype.clone = function() {
var newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i == 'clone') continue;
if (this[i] && typeof this[i] == "object") {
newObj[i] = this[i].clone();
} else newObj[i] = this[i]
} return newObj;
};
Jquery doesn't have a proper way to filter with regexes... so.... yeah... But even that needs to be modified since it only searches on the text() field of an object.
jQuery.extend(
jQuery.expr[':'], {
regex: function(a, i, m, r) {
var r = new RegExp(m[3], 'i');
//Add modifications here....
return r.test(jQuery(a).text());
}
}
);

But a way to get around the lack of regex in some cases is to remember that you can chain [attributeFilters]..
$("input[id][name$='man']").val("only this one");

And finally(for now), you can add attributes to objects with attr.
$('#target').attr("disabled", true); 




I still don't like javascript, but jquery makes working with it a lot nicer.. sorta.

Friday, October 16, 2009

Python closures explanation

While trying to figure out what exactly people meant when they said that python didn't have true closures, I found this excellent response that describes the issue perfectly.




Joel VanderWerf wrote:
> ...
>
> But in Python, the inner function only has access to the _object_, not
> to the original variable which refers to the object, and so you have to
> "box" the value inside an object if you want to have shared references.

No, you still don't undestand the issue properly. You're getting closer,
but not quite there yet.

y = 0

def foo():
global y
x = 0
def bar():
print x, y
bar()
x = y = 1
bar()
x = y = 2
bar()
x = y = 3
bar()
x = y = 4
bar()
x = y = 5

foo()

0 0
1 1
2 2
3 3
4 4

Now just as in Ruby, 0, 1, 2, 3, 4 are separate objects. It is literally
impossible to change their values. All you can do is change bindings TO
the variables. So obviously "bar" is really inheriting the _bindings_
for x and y because it is the _bindings_ that are changing.

So what's the problem? Consider this program:

y = 0

def foo():
x = 0
def bar():
print x, y
def change(z):
global y
x = y = z

change(1)
bar()
change(2)
bar()
change(3)
bar()
change(4)
bar()

foo()

The output is:

0 1
0 2
0 3
0 4

This is because Python has always adopted the rule that if you assign to
a local variable it springs into existence -- as a local. If you want to
overwrite a global variable, you have to specifically say: "please
overwrite this global." It prevents people from accidentally overwriting
globals with locals.

But there is no syntax for saying: "please overwrite this intermediate
closure variable." It would be as easy as adding a keyword
"intermediate" or "closure". It's purely a syntactic issue.

_But_ the addition would be useless in practice because this problem
almost never arises in real code. Its only purpose would be to answer
Lisp and Ruby advocates who want to say that Python doesn't really have
closures. I don't know whether Guido will ever add it for, er, closure,
but I do know that I have _never_ _once_ needed this keyword in hundreds
of thousands of lines of real Python code I have written. And I am thus
going to fight my temptation to go and bug Guido to do it so that we can
put an end to permathreads about Python's lack of closures. ;) If this
problem ever arose in my code (which it has not) then I could work
around it thus:

y = 0

def foo():
x = [0]
def bar():
print x[0], y
def change(z):
global y
x[0] = y = z

change(1)
bar()
change(2)
bar()
change(3)
bar()
change(4)
bar()

foo()

1 1
2 2
3 3
4 4

This should prove that the problem is really not deep in the Python
interpreter or anything like that. It would be a half day's work to
write the patch that added the "intermediate" keyword.

By the way, there was a time when Python really did lack closures but
there was a hacky workaround. This is where the idea that Python did not
have "real" closures became popular (because it was true). Then Python
added closures, but left out one minor feature and the minor feature
allowed the idea to persist even when it had ceased to be true.

--Paul Prescod

Monday, October 12, 2009

Errors while creating validations for django admin

TypeError at /admin/quiz/series/add/

argument of type 'NoneType' is not iterable

Request Method: POST
Request URL: http://10.0.1.72/admin/quiz/series/add/
Exception Type: TypeError
Exception Value:

argument of type 'NoneType' is not iterable

Exception Location: /usr/local/lib/python2.6/dist-packages/django/forms/models.py in save_instance, line 47



Got this error which had me stumped for a while. Turns out it's because I forgot to return self.cleaned_data at the end of my clean() and clean_<fieldname>() functions.