Nov 11, 2013

Javascript Function call() and apply() explained



First of all 
every function in JavaScript is an object
which has some methods attached to it some are toString(), call(), and apply().
Read this article if you wonder what the difference is between a function and a method.

Every JavaScript object has a toString() method, for example, and we can use the toString() method on a function object to see its source code:
function foo()
{
    alert('x');
}

alert(foo.toString());


Because functions are objects they can have their own properties and methods, and we can treat them like data. "Functions as data" is important to remember for the next post, too, but for now we'll focus on two of a function's methods: apply(), and its counterpart: call().
Let's start with the following code:
var x = 10;

function f()
{
    alert(this.x);
}

f();

Here we have a global function by the name of f(). f() uses the this keyword to reference x, but notice we don't invoke the function through an instance of an object. So what object does this reference? this will reference the global object. The global object is where we defined the variable x. The above code does work and will show the value 10 in a dialog.

Both call() and apply() are methods we can use to assign the this pointer for the duration of a method invocation. As an example, here is how we could use the call() method:
var x = 10;
var o = { x: 15 };

function f()
{
    alert(this.x);
}

f();
f.call(o);

The first invocation of f() will display the value of 10, because this references the global object. The second invocation (via the call method) however, will display the value 15. 15 is the value of the x property inside object o. The call() method invokes the function and uses its first parameter as the this pointer inside the body of the function. In other words - we've told the runtime what object to reference as this while executing inside of function f().

Fiddling with the this pointer might sound funny, even perverse, to C++, Java, and C# programmers. What's next? Dogs sleeping with cats? Working nVidia drivers for Windows Vista? It's all part of the fun that is ECMAScript.
We can also pass arguments to the target function via call():
var x = 10;
var o = { x: 15 };
function f(message)
{
    alert(message);
    alert(this.x);
}

f("invoking f");
f.call(o, "invoking f via call");

The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method.



f("invoking f");
f.apply(o, ["invoking f through apply"]);

The apply() method is useful because we can build a function like createDelegate (from the last post) that doesn't care about the signature of the target method. The function can use apply() to pass all additional arguments to the target method via an array. 
var o = { x: 15 };

function f1(message1)
{
    alert(message1 + this.x);
}

function f2(message1, message2)
{
    alert(message1 + (this.x * this.x) + message2);
}

function g(object, func, args)
{
    func.apply(object, args);
}

g(o, f1, ["the value of x = "]);
g(o, f2, ["the value of x squared = ", ". Wow!"]);

The problem here is the awkward syntax. We are forcing the caller to stuff arguments into an array just so we call apply(). Fortunately, there is a way to make the syntax easier, but we have to introduce one more topic: the arguments identifier.

In JavaScript, every function essentially has a variable length argument list. The means we can pass 5 parameters to a function even if the function only uses one argument. The following runs without error and displays "H":
function f(message)
{
    alert(message);
}

f("H", "e", "l", "l", "o");

If we did want to access the other arguments from inside f(), we can use the arguments keyword. arguments references an Arguments object, which has a length property and feels like an array.

function f(message)
{
    // message param is the same as arguments[0]    
   
    for(var i = 1; i < arguments.length; i++)
    {
        message += arguments[i];
    }
    
    alert(message); 
}

// this will say "Hello"
f("H", "e", "l", "l", "o");

Just so you know, arguments is technically not an array, even if it walks and talks like one. arguments has a length property but no split, push, or pop methods. What we can do with arguments inside our previous g() function is copy the incoming arguments after arguments[1] into an array object that we pass to apply.

var o = { x: 15 };

function f(message1, message2)
{
    alert(message1 + (this.x * this.x) + message2);
}

function g(object, func)
{           
    // arguments[0] == object
    // arguments[1] == func
    
    
    var args = []; // empty array
    // copy all other arguments we want to "pass through" 
    for(var i = 2; i < arguments.length; i++)
    {
        args.push(arguments[i]);
    }

    func.apply(object, args);
}

g(o, f, "The value of x squared = ", ". Wow!");

When we invoke g(), we can pass additional arguments as parameters instead of stuffing the arguments into an array.

At this point, we have the theoretical knowledge needed to understand call and apply, but perhaps you are already asking a question: what if I don't want to immediately invoke the target function f()? What if I just want to arrange all the players in this little drama so that I can invoke f() at some later point (as an event handler, for example), but still have this referencing the desired object.


Using call to invoke an anonymous function

In this purely constructed example, we create anonymous function and use call to invoke it on every object in an array. The main purpose of the anonymous function here is to add a print function to every object, which is able to print the right index of the object in the array. Passing the object as this value was not strictly necessary, but is done for explanatory purpose.
var animals = [ {species: 'Lion', name: 'King'},
{species: 'Whale', name: 'Fail'} ];

for (var i = 0; i < animals.length; i++)
{
(function (i) {
this.print = function ()
  {
    console.log('#' + i + ' ' + this.species + ': ' + this.name);
  }
 this.print();
}).call(animals[i], i); }


Hope this will help you understand, Feel free to ask anything

Jul 2, 2013

IOS Xcode Create a modal window

Create  a modal window for IOS application in Xcode 

1. Create new view controller either programatically or using a nib file, design it the way you want your modal window to be.
2. Name it youtubeplayer (say).
3. Import its header file into the main view controller (obviously).
4. From the main view controller put the below code into any event. ( clicking of button, or table row selected etc.) 

youtubeplayer *yt = [[youtubeplayer alloc]  initWithNibName:@"youtubeplayer" bundle:[NSBundle mainBundle]];    yt.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;    yt.modalPresentationStyle = UIModalPresentationFormSheet;    [self presentViewController:yt animated:YES completion:^{        NSLog(@"this is calleed");    }];    CGRect r = CGRectMake(self.view.bounds.size.width/2 - 350,                          self.view.bounds.size.height/2 - 200,                          700, 400);    r = [self.view convertRect:r toView:yt.view.superview.superview];    yt.view.superview.frame = r;

Also now you will need a button on the modal window opened to close it.
simply create a button or what ever element you are comfortable with and put in the following code in it.

- (IBAction)closeModal:(id)sender {
    [self dismissModalViewControllerAnimated:YES];
}

that's it Now you are good to go.


If need any help You can ask in comments.

Happy Coding :)

Jul 1, 2013

Retrive the cover images of videos from YouTube


Retrive the cover images of videos from YouTube

Each YouTube video has 4 generated images. They are predictably formatted as follows:
http://img.youtube.com/vi/<insert-youtube-video-id-here>/0.jpg
http://img.youtube.com/vi/<insert-youtube-video-id-here>/1.jpg
http://img.youtube.com/vi/<insert-youtube-video-id-here>/2.jpg
http://img.youtube.com/vi/<insert-youtube-video-id-here>/3.jpg
The first one in the list is a full size image and others are thumbnail images. The default thumbnail image (ie. one of 1.jpg2.jpg3.jpg) is:



http://img.youtube.com/vi/<insert-youtube-video-id-here>/default.jpg

For the high quality version of the thumbnail use a url similar to this:










http://img.youtube.com/vi/<insert-youtube-video-id-here>/hqdefault.jpg

There is also a medium quality version of the thumbnail, using a url similar to the HQ:
http://img.youtube.com/vi/<insert-youtube-video-id-here>/mqdefault.jpg
For the maximum resolution version of the thumbnail use a url similar to this:
(if it exists for certain videos youtube does not have a heigh resolution cover pic) .

http://img.youtube.com/vi/<insert-youtube-video-id-here>/maxresdefault.jpg
All of the above urls are available over https too. Just change http to https in any of the above urls.
Alternatively, you can use the YouTube API to get thumbnail images.

Mar 1, 2013

MySQL FULLTEXT Indexing and Searching


MySQL has supported FULLTEXT indexes since version 3.23.23VARCHAR and TEXT Columns that have been indexed with FULLTEXT can be used with special SQL statements that perform the full text search in MySQL.
To get started you need to define the FULLTEXT index on some columns. Like other indexes, FULLTEXT indexes can contain multiple columns. Here's how you might add a FULLTEXT index to some table columns:

ALTER TABLE news ADD FULLTEXT(headline, story);

Once you have a FULLTEXT index, you can search it using MATCH and AGAINST statements. For example:


SELECT headline, story FROM news
WHERE MATCH (headline,story) AGAINST ('Hurricane');

The result of this query is automatically sorted by relevancy.

MATCH

The MATCH function is used to specify the column names that identify your FULLTEXT collection. The column list inside the MATCHfunction must exactly match that of the FULLTEXT index definition, unless your search in boolean mode (see below).

AGAINST

The AGAINST function is where your full text search query goes. Besides the default natural language search mode, you can performboolean mode searches, and use query expansion.

Boolean Mode Searches

SELECT headline, story FROM news
WHERE MATCH (headline,story)
AGAINST ('+Hurricane -Katrina' IN BOOLEAN MODE);

The above statement would match news stories about hurricanes but not those that mention hurricane katrina.
See the MySQL documentation on Boolean Mode searches for more info.

Query Expansion

The Blind Query Expansion (or automatic relevance feedback) feature can be used to expand the results of the search. This often includes much more noise, and makes for a very fuzzy search.
In most cases you would use this operation if the users query returned just a few results, you try it again WITH QUERY EXPANSION and it will add words that are commonly found with the words in the query.

SELECT headline, story FROM news
WHERE MATCH (headline,story)
AGAINST ('Katrina' WITH QUERY EXPANSION);

The above query might return all news stories about hurricanes, not just ones containing Katrina.

A couple points about Full-Text searching in MySQL:
  • Searches are not case sensitive
  • Short words are ignored, the default minimum length is 4 characters. You can change the min and max word length with the variables ft_min_word_len and ft_max_word_len
  • Words called stopwords are ignored, you can specify your own stopwords, but default words include thehavesome - see default stopwords list.
  • You can disable stopwords by setting the variable ft_stopword_file to an empty string.
  • Full Text searching is only supported by the MyISAM storage engine.
  • If a word is present in more than 50% of the rows it will have a weight of zero. This has advantages on large datasets, but can make testing difficult on small ones.

Feb 15, 2013

Hierarchical queries in MySQL, Tree structures

Hierarchical queries in MySQL, Managing tree like structures

I was wondering how to implement a hierarchical query in MySQL (using the ancestry chains version) for a single row, such that it picks up the parents (if any) and any children (if any).
The idea is, I want to be able to jump in at any point, provide an Id of some sort, and be able to draw out the entire hierarchy for that Id, both upwards and downwards.
We need to combine two queries here:
  1. Original hierarchical query that returns all descendants of a given id (a descendancy chain)
  2. A query that would return all ancestors of a given id (an ancestry chain)
An id can have only one parent, that’s why we can employ a linked list technique to build an ancestry chain, like shown in this article:
Here’s the query to to this (no functions required):
SELECT  @r AS _id,
         (
         SELECT  @r := parent
         FROM    t_hierarchy
         WHERE   id = _id
         ) AS parent,
         @l := @l + 1 AS lvl
 FROM    (
         SELECT  @r := 1218,
                 @l := 0,
                 @cl := 0
         ) vars,
         t_hierarchy h
WHERE    @r <> 0
To combine two queries, we can employ a simple UNION ALL.
The only problem that is left to preserve the correct level, since the ancestry chain query conts levelbackwards, and the hierarchical query will count it starting from zero.

Let’s create a sample table and see what we get:


CREATE TABLE t_hierarchy (
02.id int(10) unsigned NOT NULL AUTO_INCREMENT,
03.parent int(10) unsigned NOT NULL,
04.PRIMARY KEY (id),
05.KEY ix_hierarchy_parent (parent, id)
06.) ENGINE=InnoDB DEFAULT CHARSET=utf8;
07. 
08.DELIMITER $$
09.CREATE PROCEDURE prc_fill_hierarchy (level INT, fill INT)
10.BEGIN
11.DECLARE _level INT;
12.DECLARE _fill INT;
13.INSERT
14.INTO    t_hierarchy (id, parent)
15.VALUES  (1, 0);
16.SET _fill = 0;
17.WHILE _fill < fill DO
18.INSERT
19.INTO    t_hierarchy (parent)
20.VALUES  (1);
21.SET _fill = _fill + 1;
22.END WHILE;
23.SET _fill = 1;
24.SET _level = 0;
25.WHILE _level < level DO
26.INSERT
27.INTO    t_hierarchy (parent)
28.SELECT  hn.id
29.FROM    t_hierarchy ho, t_hierarchy hn
30.WHERE   ho.parent = 1
31.AND hn.id > _fill;
32.SET _level = _level + 1;
33.SET _fill = _fill + POWER(fill, _level);
34.END WHILE;
35.END
36.$$
37.DELIMITER ;
38. 
39.DROP FUNCTION IF EXISTS hierarchy_connect_by_parent_eq_prior_id;
40. 
41.DELIMITER $$
42. 
43.CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INTRETURNS INT
44.NOT DETERMINISTIC
45.READS SQL DATA
46.BEGIN
47.DECLARE _id INT;
48.DECLARE _parent INT;
49.DECLARE _next INT;
50.DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;
51. 
52.SET _parent = @id;
53.SET _id = -1;
54. 
55.IF @id IS NULL THEN
56.RETURN NULL;
57.END IF;
58. 
59.LOOP
60.SELECT  MIN(id)
61.INTO    @id
62.FROM    t_hierarchy
63.WHERE   parent = _parent
64.AND id > _id;
65.IF @id IS NOT NULL OR _parent = @start_with THEN
66.SET @level = @level + 1;
67.RETURN @id;
68.END IF;
69.SET @level := @level - 1;
70.SELECT  id, parent
71.INTO    _id, _parent
72.FROM    t_hierarchy
73.WHERE   id = _parent;
74.END LOOP;      
75.END
76.$$
77. 
78.DELIMITER ;
79. 
80.START TRANSACTION;
81.CALL prc_fill_hierarchy(6, 5);
82.COMMIT;


Now, let’s try to UNION ALL the queries as is:
SELECT  CONCAT(REPEAT('    ', lvl  - 1), _id) AS treeitem, parent, lvl AS level
FROM    (
        SELECT  @r AS _id,
                (
                SELECT  @r := parent
                FROM    t_hierarchy
                WHERE   id = _id
                ) AS parent,
                @l := @l + 1 AS lvl
        FROM    (
                SELECT  @r := 1218,
                        @l := 0,
                        @cl := 0
                ) vars,
                t_hierarchy h
        WHERE   @r <> 0
        ORDER BY
                lvl DESC
        ) qi
UNION ALL
SELECT  CONCAT(REPEAT('    ', level  - 1), CAST(hi.id AS CHAR)), parent, level
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 1218,
                        @id := @start_with,
                        @level := 0
                ) vars, t_hierarchy
        WHERE   @id IS NOT NULL
        ) ho
JOIN    t_hierarchy hi
ON      hi.id = ho.id

treeitemparentlevel
106
215
724
3873
165382
12181651
547312181
2479654732
2479754732
2479854732
2479954732
2480054732
547412181
2480154742
2480254742
2480354742
2480454742
2480554742
547512181
2480654752
2480754752
2480854752
2480954752
2481054752
547612181
2481154762
2481254762
2481354762
2481454762
2481554762
547712181
2481654772
2481754772
2481854772
2481954772
2482054772
36 rows fetched in 0.0014s (0.1447s)
We see that the hierarchical order is mangled: the first resultset is upside down, the second one is starting from level = 1.
To fix it, we need to change the code that calculates level a little.
First, we need to reverse the ancestry part.
This can be easily done by sorting it on lvl DESC:
SELECT  CONCAT(REPEAT('    ', level  - 1), _id) AS treeitem, parent, level
FROM    (
        SELECT  @r AS _id,
                (
                SELECT  @r := parent
                FROM    t_hierarchy
                WHERE   id = _id
                ) AS parent,
                @l := @l + 1 AS level
        FROM    (
                SELECT  @r := 1218,
                        @l := 0,
                        @cl := 0
                ) vars,
                t_hierarchy h
        WHERE   @r <> 0
        ORDER BY
                level DESC
        ) qi

treeitemparentlevel
106
215
724
3873
165382
12181651
6 rows fetched in 0.0003s (0.0684s)
We now have it in correct order but with wrong level values.
Since a level is essentially a rownum here, we can just calculate it as a rownum instead:
SELECT  CONCAT(REPEAT('    ', level  - 1), id) AS treeitem, parent, level
FROM    (
        SELECT  _id AS id, parent,
                @cl := @cl + 1 AS level
        FROM    (
                SELECT  @r AS _id,
                        (
                        SELECT  @r := parent
                        FROM    t_hierarchy
                        WHERE   id = _id
                        ) AS parent,
                        @l := @l + 1 AS level
                FROM    (
                        SELECT  @r := 1218,
                                @l := 0,
                                @cl := 0
                        ) vars,
                        t_hierarchy h
                WHERE   @r <> 0
                ORDER BY
                        level DESC
                ) qi
        ) qo
treeitemparentlevel
101
212
723
3874
165385
12181656
6 rows fetched in 0.0003s (0.0712s)
We disregard the previously selected level at all, leaving it only inside the inline view qi for ordering purposes.
Now, we need to merge the descendancy tree query, but with levels starting from 6, not from 1.
Since this query will come after the ancestry one, we can use accumulated value of @cl (which we used to calculate level in the previous query) as a seed.
To do that, we can take the level returned by the descendancy tree query, and just add @cl to it.
The only problem it to determine when we should increment @cl and when we should add it to level.
We will just use a boolean field which will help us to tell the sets apart.
Here’s the query to do it:
SELECT  CONCAT(REPEAT('    ', level - 1), CAST(id AS CHAR)),
        parent,
        level
FROM    (
        SELECT  id, parent, IF(ancestry, @cl := @cl + 1, level + @cl) AS level
        FROM    (
                SELECT  TRUE AS ancestry, _id AS id, parent, level
                FROM    (
                        SELECT  @r AS _id,
                                (
                                SELECT  @r := parent
                                FROM    t_hierarchy
                                WHERE   id = _id
                                ) AS parent,
                                @l := @l + 1 AS level
                        FROM    (
                                SELECT  @r := 1218,
                                        @l := 0,
                                        @cl := 0
                                ) vars,
                                t_hierarchy h
                        WHERE   @r <> 0
                        ORDER BY
                                level DESC
                        ) qi
                UNION ALL
                SELECT  FALSE, hi.id, parent, level
                FROM    (
                        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
                        FROM    (
                                SELECT  @start_with := 1218,
                                        @id := @start_with,
                                        @level := 0
                                ) vars, t_hierarchy
                        WHERE   @id IS NOT NULL
                        ) ho
                JOIN    t_hierarchy hi
                ON      hi.id = ho.id
                ) q
        ) q2

CONCAT(REPEAT(‘ ‘, level – 1), CAST(id AS CHAR))parentlevel
101
212
723
3874
165385
12181656
547312187
2479654738
2479754738
2479854738
2479954738
2480054738
547412187
2480154748
2480254748
2480354748
2480454748
2480554748
547512187
2480654758
2480754758
2480854758
2480954758
2481054758
547612187
2481154768
2481254768
2481354768
2481454768
2481554768
547712187
2481654778
2481754778
2481854778
2481954778
2482054778
36 rows fetched in 0.0016s (0.1514s)
One more thing:  use this if extremely necessary, and for small trees,, some times it crashes the Mysql server,
im still working on some more efficient solution.

Till Happy coding :)