It is faster if you stand on the escalators

5720026-3x2-700x467

As State tells us in its article: Don’t Walk on Escalators. It’s Faster if Everyone Stands.

A survey from the Greenwich University in 2011 found out that 75% of the people from the metro do not walk when they are at the escalators while the other 25% do. Firstly, we can easily see that set apart half the escalator for only the 25% of the people does not make too sense. In addition, people usually keep more distance when they are walking than when they are still.

So it seems this is a studied issue that has been simulated many times, and with always the same conclusion: If everyone stands still, the escalator can take on more passengers per minute.

For instance, the simulations made by “Transport of London” determine that an escalator full of stopped people is able to carry 112,5 people per minute. And the same escalator with 2 queues, one for whom are walking and other for the stopped people, makes the flux decreases to 81,25 people per minute.

More recently, a real test confirmed the simulation results: For some weeks, the London metro workers were forcing the passengers to keep still on the escalators. Well, they tried to do as much as they could, asking kindly to stay still, or even blocking the way with couples holding hands, and other ruses to block the walkers.
Although it was impossible to stop everybody, the result pointed that the same escalator which used to carry 12.745 people per hour (at rush hour), was able to carry 16.220 people within the same time.

The problem, of course, is that an individual person goes faster when he walks on the escalator. In fact, it turns impossible and complicated not to walk for many people, especially if they are in a hurry.

 

More details about it at The Guardian: The tube at a standstill: why TfL stopped people walking up the escalators.

From: Mircosiervos – Es más rápido para todos permanecer quieto en las escaleras mecánicas.

Categories:From Microsiervos

Model car at 204 mph speed

The model vehicle of the video reaches the awesome speed of 204 mph, which means that for a moment it turns from a toy to a killing weapon. Just as a lost particle from the CERN accelerator.

Anyway, at this competition modality for model vehicles, the car is tied to the stake in the center of the circuit, which has about 20 meters wide (of diameter). The basic concept is similar to the cable-piloted aircraft, except for in this case the driver doesn’t control the steering nor the throttle of the car. The only aim is to go faster and faster before it runs out of fuel.

The vehicle can be powered by a combustion engine (usually by burning alcohol), or by electric engines. The current speed record is set almost at 214 mph. This VoltsWagen is a competition model with an electric engine, able to reach the 200 mph on a good day.

***

But wait! Check this out, too

This remote-control car race may be more thrill than the last 5 F1 championships, and not only because of the flying overtake.

 

From: Microsiervos – Un coche a escala a 330 km/h + una emocionante carrera de coches teledirigidos

Categories:From Microsiervos

Number base conversion from 64 to 58

If you are only looking for an example, you can find one here in my GitHub.

It would seem that a number base conversion is easy. And it is unless you deal with very large numbers. In this case, the problem gets worse. Here I explain how I developed an efficient base change algorithm that will take simple execution requisites for large number conversions.

As this nice page explains, the simplest way to convert base number is this algorithm:

// M = input number, N = output base,
result = “”
if M < N, result = ‘M’ + result. Stop.
S = M mod N, result = ‘S’ + result
M = M/N
goto 2

For example, if we try to convert 100 from base 10 to base 16, we should follow these steps:

M = 100, N = 16
100 < 16 ?
S = 4, result = ‘4’
M = 100/16 = 6
6 < 16 ?
result = ’64’

And therefore, we’ll get that 100 is equal 64 in base 16.

However, this algorithm involves working with the whole input number in math operations (such as division and modulus). If you tried to convert a long number (let’s suppose a long number has more than 30 digits), it would be needed a very long numeric data type for this operations. For instance, to allow a 60 hexadecimal digit number, we would need a 240-bit (30 bytes) data type number, which does not exist in most languages (usually the largest types are long and double-precision, with 64 bit).

So, I tried to find out a different way to manage a base conversion, where it would be possible to slice the number and work with their parts independently. It came to me that there must be an easier way to shift a number by only 1 base. And actually there is.

Let’s try to explain it with a simple example. Imagine you want to convert a 2 digit number from base 16 to base 15, for instance, the number “43 hex”. The second digit of this number (4) means that in fact, we have added 4*16 times the 1 value. If we try to allocate the same value in a 15 base number, we could find easily that: (4*16) = 4 * (4*15), so the second digit remains as “4”, but we must add the same second digit value to the first digit value (4+3). Finally, we get that “43” base 16 = “47” base 15. Notice that we did this conversion only with a simple and independent digit sum.

Well, to be fair let’s see the worst case in this conversion example. Let’s try to convert in the same way the number “FF hex” to 15 base. If we apply the same rule, by decoding the number as “FF = (F * 16) + F = (F * 15) + F + F”, we’ll have an overflow at the first digit (F + F = 1E), so we must add (carry) this “1” spent value to the second digit. And then, the second digit “F + 1” will also have another overflow, and will also take another carry value to the next digit. So finally we’ll get that “FF hex” equals to “1FE” in base 15. In fact, the method is the same, though we must pay attention to the carry values.

Now let’s try to convert a 4 digit number “5A78 hex”. In order to introduce yourself to my algorithm’s notation, I’m going to write this number as an integer array: “5A78 hex” = [5,10,7,8]. If we try to apply the same method, we’ll find that “[5,10,7,8] = (5 * 16³) + (10 * 16²) + (7 * 16) + 8”. By decoding every part independently, we’ll get:

(8 * 16⁰) = (8 * 15⁰) = [0,0,0,8]
(7 * 16¹) = (7 * 15) + 7 = [0,0,7,7]
(10 * 16²) = (10 * 15²) + (10 * 2 * 15) + 10 = [0,10,(10*2),10]
(5 * 16³) = (5 * 15³) + (5 * 3 * 15²) + (5 * 3 * 15) + 5 = [5,(5*3),(5*3),5]

It means that, for shifting each digit, we must add the following values:

5 10 7 8  
      8 the first digit needn’t be shifted
    7 7 to shift the second digit
  10 20 10 to shift the third digit
5 15 15 5 to shift the fourth digit
5 25 42 30 without carrying the overflows
6 12 14 0  

And thereafter, without missing the overflow carries, we’ll get the result = [6,12,14,0].
Notice that the same matrix would work for any other 4 digit conversion since we express the accumulators (the numbers we must add to shift the digits) as a multipliers of the original digits:

d c b a
      a
    b b
  c 2c c
d 3d 3d d

So, by following this method we can increase this matrix in size to the needed digits, and then apply simple sums for each digit. For instance, the 8 digit conversion matrix  is equal to:

h g f e d c b a
              a
            b b
          c 2c c
        d 3d 3d d
      e 4e 6e 4e e
    f 5f 10f 10f 5f f
  g 6g 15g 20g 15g 6g g
h 7h 21h 35h 35h 21h 7h h

We can also apply this to convert, for example, the number “39485A78 hex”. We only must apply this fix multiplier matrix:

              1
            1 1
          1 2 1
        1 3 3 1
      1 4 6 4 1
    1 5 10 10 5 1
  1 6 15 20 15 6 1
1 7 21 35 35 21 7 1

To the specific values:

  3 9 4 8 5 10 7 8
8               8
7             7 7
10           10 20 10
5         5 15 15 5
8       8 32 48 32 8
4     4 20 40 40 20 4
9   9 54 135 180 135 54 9
3 3 21 63 105 105 63 21 3
  3 30 121 268 362 311 169 54
  5 9 5 8 8 7 7 9

Once here, you should have noticed that the next goal should be to set a method for building any size multipliers matrix. Indeed, as you may have graphically seen, there’s an easier way to build the matrix without decoding each digit into a mathematical expression. Instead, we can iterate each digit and get the next multiplier value by adding the multiplier value at its previous position (at its right position in the grid). It would be something like:

 

gapi

We could easily get this with the following double loop:

var buffer_mult = [1,0,0,0,0,.....]; // First multiplier must be set as 1
for (var cdig = 0; cdig < buffer_mult.length; cdig++) {
    for (var t = cdig; t > 0; t--) buffer_mult[t] += (buffer_mult[t - 1] || 0);
}

This method always works for every number.

However, in the same way as the matrix grows, we’ll get higher multiplier values. We can reach several millions at a 30 digit conversion though there’s an optimization to avoid this lack. Shifting the multiplier values up, with a modulus and carry values at the conversion base, we could manage to avoid big numbers getting the same result.

For instance, in the last example we can optimize the seventh interation by shifting up the values over 15:

  1 6 15 20 15 6 1
    +1 +1 +1      
  1 7 1 6 0 6 1
1 8 8 7 6 6 7 1

and get the same result with fewer multiplier values.

.

Practical case: Convert from hexadecimal to 58 base

.

A practical case of this method could be used to convert from base 64 to base 58. It is usual to need number conversion to base 58 when you’re dealing with bitcoin addresses, URL shorteners and others. Therefore, it is nice to have a good way to do it.

I did it by applying this method with good results. I applied 6 times the algorithm, shifting from base 64 to base 58. I had good results with some 80 digit hexadecimal numbers. Fast executions, with less than 50.000 iterations, and maximum variable’s values under 200.000.

If you’d like to check it out, you can find this example developed in a simple html/javascript page just here in my GitHub repository, or try it working here.

gapi.png

Or if you are not still satisfied, here’s another page where you can find another ways to get the same.

 

 

 

 

Working with google APIs

We’ve already seen how to develop a whole web app using the «Web App Scripts». However, many times we would like to keep our web app into another place/server, so in this case we must use the google APIs to interact with the google services. Let’s see how to do it.

Grant access to the APIs

Before coding anything, we must grant the access to the APIs we’re going to use into our google account.

So go to : https://console.developers.google.com/ and create a new project (for instance, project2):

gapi

Then, go to «APIs & auth», «APIs» option of the new Project, and there select the API you want to enable for the project. In our example it will be the «Drive API» :

gapi

And set “enable” the API for the project :

gapi

You may add more information about why your app needs to be connected into the Google Drive Service :gapi

Now go to the «APIs & auth», «Credentials» option, and add a new credential of «OAuth 2.0 client ID» :

gapi

There are 2 authentication methods depending on which sort of use it will be needed:

  1. We could launch requests to APIs which doesn’t need to access private data in the google account, and therefore it doesn’t need authorization, so we can use a simple access with gapi.client.setApiKey(API KEY);
  2. If we have to access private data with the APIs, we have to use the OAuth 2.0.

In the example, we’ll use the OAuth 2.0 method, so we’ll work with private data.

However, before creating it, you must setup the «Consent Screen». This is the screen that will be shown to get the authorization when the app tries to access google API for first time. So go to set it up :

gapi

type a «Product Name» and save it.

gapi

Afterwards, choose the «Web application» type and – for more safety – I advise to filter the origin domains where the app will access (in the example, we’ll use a local server, so we’ll access from local http://localhost) :

gapi

Then, you will get the «Client ID» and «Client Secret» keys. Keep your «Client ID», because we’ll need it later.

gapi

So we’ve already got it. Now we can access the services using the API.

The first time you try to access to the API, if the request parameter «immediate» is false (we’ll see it later), a window screen pop up will ask you for login into google account (if you’re not yet):

gapi

and also to allow the access to the google service:

gapi

Access the API

Now that we have the access available, let’s going to see how to use it.
We’ve built this simple html page to show an easy example :

<!DOCTYPE html>

<html>

<head>

https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js

https://apis.google.com/js/client.js

var clientId = ’10…………….apps.googleusercontent.com’;

var scopes = ‘https://www.googleapis.com/auth/drive.metadata.readonly&#8217;;

function checkAuth() {

$(‘body’).append(‘

The authorization request has been launched

‘);

gapi.auth.authorize({

‘client_id’: clientId,

‘scope’ : scopes,

‘immediate’: true

},

handleAuthResult);

}

function handleAuthResult(authResult) {

if (authResult && !authResult.error) {

$(‘body’).append(‘

The authorization request has been succesful

‘);

$(‘.send_request’).removeAttr(‘disabled’);

} else {

$(‘body’).append(‘

There was an ERROR!

‘);

}

}

</head>

<body style=”width: 100%; height: 100%; overflow: hidden;”>

<h1> Google API access example </h1>

<button id=”authorize-button1″ onclick=”checkAuth();”> check Authorization </button>

<button class=”send_request” onclick=”method_1_request();” disabled=”true”> Request method 1 (request) </button>

<button class=”send_request” onclick=”method_2_request();” disabled=”true”> Request method 2 (load) </button>

<button class=”send_request” onclick=”method_3_request();” > Request method 3 (CORS) </button>

</body>

</html>

The first we need is include the google API’s JS library into our page (https://apis.google.com/js/client.js). We’re going to launch the request with a javascript code, although there’re many other ways to do it. You can also use PHP, Java, Python, etc.. (https://developers.google.com/api-client-library/).

As you can guess, before anything the app has to authenticate the client access to the API services. In the example, as we’ve set it up before, we’ll use the OAuth 2.0. As you can see in the code, we put a button that calls a javascript function «checkAuth», where we use the gapi.auth.authorize() function. This uses 2 parameters. The first parameter is an object with the following values:

  1. client_id: This is the ID you’ve got after setting up the google API service access. Just put the code there, or use an input parameter to set it.
  2. scope: Here we have to specify which scope (part of the service) we will use. Each API has many scopes, and depending on what our app wants to do, we must choose the most suitable. In the example, we’re using the «drive.metadata.readonly» scope of the Google Drive API. However we could use many others.
  3. immediate: This (true/false) value – as we’ve seen before – sets the app to show the authorization popup window, or not. (true = it doesn’t show the popup / false = it does show the popup).

And the second parameter, is a handler function (handleAuthResult), to be called after the request finishes, in order to handle the answer. The most common we should do here is to test the result of the request with the parameter (authRestful), and then proceed as the app needs.

If you try to execute the example, you’ll see that there’s an authorization request to the API:

gapi

gapi

As you may know, the google API works as a RESTful method. It means that the client (javascript, or any else we’re using) and the server (google) uses a http URL structured interface to compose the messages for sending requests and responses. You can learn more about this process there.

So, let’s see how to build and send a request. Here we have 3 different options. We can either use a simple request call (with gapi.client.request), or a faster technique, that loads previously the API interface. Even more, we also could build manualy an XHR request (with CORS).

Method 1: gapi.client.request

The easier one. We can quickly compose a http request using the gapi.client.request function. This uses an object parameter where we must set the required values to build the request, as the «path» (in the example, we’re using the drive file list request), the «method» (GET by default for reading, although it could be POST / PUT / DELETE), «params» for specific parameters of the request, and «headers» and «body», which we’re not going to use for now.

function method_1_request() {
    $(‘body’).append(‘<p>Drive API direct request has been launched</p>’);
    var restRequest = gapi.client.request({
       ‘path’ : ‘https://www.googleapis.com/drive/v2/files&#8217;,
        ‘method’ : ‘GET’,
        ‘params’ : { ‘maxResults’: 10, ‘q’ : ‘trashed=false’ }
        });
    restRequest.then(
       function(resp) { load_result(resp.result); }, // Success function
       function(reason) { $(‘body’).append(‘<p>There was an ERROR!</p>’); }); // Error function
}

After the request, as we have previously set with the «restRequest.then», it will launches the response handled function (load_result if it goes ok).

The request we’ve used for the example (drive/v2/files), as you may have already read in the documentation, asks google Drive for a metadata list of our stored files, and returns it in a JSON structure:

{
“kind” : “drive#fileList”,
“etag” : etag,
“selfLink” : string,
“nextPageToken” : string,
“nextLink” : string,
“items” : [ files Resource ]
}

As an example, we could print it into the page with and easy dynamic script :

function load_result(resp) {
    $(‘body’).append(‘<p>Drive API direct request has been successful</p>’);
    var files = resp.items;
    if (files && files.length > 0) {
        $(‘body’).append(‘<ul>’);
        for (var i = 0; i < files.length; i++) {
           $(‘body’).append(‘<li>’ + files[i].title + ‘ – ‘ + files[i].id + ‘</li>’);
        }
        $(‘body’).append(‘</ul>’);
    } else {
        $(‘body’).append(‘<p>No files found.</p>’);
    }
}

And get the following result :

gapi

As you’ve seen, after pushing the button, the page launched a XHR request to talk with the API, with the URL and defined parameters:

gapi

Method 2: gapi.client.load

There’s another way to do exactly the same, though with a better performance. We could load the full client API’s interface, with the gapi.client.load() function, and henceforth use it to launch many requests. As you can imagine, it should be faster in a many requests scenario.

After loading the API interface, we can call all its available requests (for instance, those of the Drive API) through each of its functions (like gapi.client.drive.files.list). So we can manage to the same result as in the last method with the following code:

function method_2_request() {
    gapi.client.load(‘drive’, ‘v2’,
function() {
$(‘body’).append(‘<p>Drive API interface loaded</p>’);
var request = gapi.client.drive.files.list({ ‘maxResults’: 10, ‘q’ : ‘trashed=false’ });
request.execute(load_result);
}
);
}

As you can see, the result is the same, and the XHR request has the same structure and parameters :

gapi

Method 3: Direct request with CORS

We have also another method to send a request to a google API: with a direct CORS request.

To take it lighter, we may just load the auth.js library instead of the whole client.js :

https://apis.google.com/js/auth.js <!– use this for only CORS auth –>
https://apis.google.com/js/client.js <!– use this for full client API –>

and then, after getting permission from the gapi.auth.authorize function, built the XHR request directly:

function method_3_request() {
$(‘body’).append(‘<p>Launching a manual request with CORS</p>’);
gapi.auth.authorize({
client_id : clientId,
scope : scopes,
immediate : true},
function() {
var oauthToken = gapi.auth.getToken();
var xhr = new XMLHttpRequest();
var url_request = ‘https://www.googleapis.com/drive/v2/files?maxResults=10‘; // + ‘&access_token=’ + encodeURIComponent(oauthToken.access_token);
$(‘body’).append(‘<p>xhr: ‘ + url_request + ‘</p>’);
xhr.open(‘GET’, url_request);
xhr.setRequestHeader(‘Authorization’, ‘Bearer ‘ + oauthToken.access_token);
xhr.onload = function() {
var obj_res = JSON.parse(xhr.responseText);
load_result(obj_res);
};
xhr.send();
});
}

This is the same way as if we would have buit a simple XMLHttpRequest.

Nevertheless, we shouldn’t forget adding the authorization token to the request. We have 2 ways to do it:

  1. Add the access_token parameter to the URL:
    var oauthToken = gapi.auth.getToken();
    var url_request = ‘https://www.googleapis.com/drive/v2/files?maxResults=10‘ + ‘&access_token=’ + encodeURIComponent(oauthToken.access_token);
  2. Or add it to the request’s header (with the setRequestHeader function):
    var oauthToken = gapi.auth.getToken();
    xhr.setRequestHeader(‘Authorization’, ‘Bearer ‘ + oauthToken.access_token);

There’s more info about this method right here.

Categories:Uncategorized

How to use Google App Scripts

Google has a huge collection of tools which allow developers interact with its services.

gapi1

One of my favourites is the Google App Scripts. This a great tool that allow us to develop software that can work together with the most Google common services, as Gmail, Calendar, Drive, Maps, Translator, etc. Actually, this is very similar to an API, but in my opinion, what Google people are offering here is something more powerful, and easier to use, than the Google APIs.

However, we can always use the Google APIs with the same aim, but for non complex aplications I think it is better to use “Google App Scripts”.

gapi2

To work with “Google App Scripts” we need a Google account. So all the references to the Google Services we are going to use, are going to point to the ones of the logged session in the browser.

“Google App Script” can be used in several ways. We are not going to talk about scripts integrated into the Google services. Rather we are going to suppose that we have a personal Web App, and we want to link it to one of our Google services.

At this point, we have 2 choices:

  • We can create our Web App completely as a “Google App Script”.
  • Or we can create a Script, and use it as an API, requested from another Web App.

We’re going to start with the first case.

Create a Web App Script

Beyond the “App Scripts”, we can also write an host a whole html dynamic page. The only thing we need to start, is a google account with a Google Drive service. The project will be stored as a file into your Google Drive unit. So you can create one directly with the Drive New File button:

gapi1

or going directly to this URL: https://script.google.com

Both cases, we’ll get the start wizard, where there are many options, but what we are looking for is the last of the left column «Web App»

gapi1

After choosing, we’ll get that framework with an implemented example :

Apps Script Framework

As you can see, the project has 4 files :

  1. Code.gs : Here we must write our Google App Scripts. With this functions we can bind our javascript code with Google Services.
  2. Index.html : This is the main html file of our web page.
  3. Javascript.html : Here we can write the javascript code for our web app.
  4. Stylesheet.html :  Here we can write the CSS styles for our web app.

Let’s try to execute the project:

  1. Go to the menu -> Publish -> Deploy as a web app
    gapi1
  2. Choose a name for the project (f.e. project_1).
    gapi1
  3. Select the Project options and access permissions.
    gapi1
  4. And then we’ll get an URL, ended with “/exec“, like this «https://script.google.com/macros/s/[…ID…]/exec».
    gapi1

This URL contains de ID of the Web App. You can change the last part of it in order to work with it. The possible endings are:

  • /exec     With this URL, you will send the request for the published version of the Web App, and get the HTML main page.
  • /dev       With this one, you will also send the request, but rather than the last published version, you’ll get the currently developed version of the Web App.
  • /edit      With this one, you will be redirected to the “web framework” where Google allows to develop the Web App.

If we try to go to the /exec url (in a new browser window), the first time we try to launch the app, Google will ask for grant for it. So give it permission.

gapi1

And finally we will get the result page. The example Web App shows a list with the name of our 20 first files in our Google Drive main folder.

gapi1

Let’s going to see how does it work.

Initial funcion doGet()

When we launch the a GET request URL (ended with /exec), the first what Google executes is the «doGet(e)» function, stored in the Code.gs file

gapi1

We can pass “GET parameters” to this function, collected in the “e” main parameter. For example, if I called the URL with “https://script.google.com/macros/s/%5B……%5D/exec?folderId=id001“, we could read (in the doGet function) the folderId value as e.parameter.folderId.

After recieving the GET request, it constructs a template object, taking the “Index.html” template file with the HtmlService.createTemplateFromFile() function.

If there’s a “folderId” parameter into the URL, it passes this value to the template variable, or ‘root’ value if not. It means that everywhere where there’s a <?=folderId?> in the template code, will be translated by the same value we’ve given to it.

And then, the template object launches 3 methods and returns the result.

  1. With the setSandboxMode(), the result web page is served into an iFrame structure, as a sandbox, in order to protect the client browser to execute malicious javascript code.
  2. With setTitle(), we can set a Window title.
  3. With evaluate(), the template code is evaluated, converted and returned as a final HTML code.

As you must have realized, this doGet() function only return an HTML code for our main page. We could write a simpler function like that :

function doGet(e) {
return HtmlService.createHtmlOutput(‘<html> <body> <p> Hello World </p> </body> </html’);
}

and after the URL request we would get this simple html page.

Template file Index.html

Now, let’s take a glance to the Index.html template file :

gapi1

As you can see, there are some <?=folderId?> template tabs, which as we know they will be overwritten with the URL parameter value.

However, there are also another <?!= HtmlService.createHtmlOutputFromFile(‘[file name]’).getContent(); ?> template tabs.

When the template is evaluated, the createHtmlOutputFromFile(”) function creates a new HtmlOutput object, and loads all the html content of the file into the final html page result. So, in this case, it takes the ‘Stylesheet.html‘ and ‘Javascript.html‘ files, and loads all their content into the final served page

<!DOCTYPE html>
<html>
<head>
<base target=”_top”>

[All the Stylesheet.html content]
var folderId = ‘root’;

[All the JavaScript.html content]

</head>


</html>

If you wish, you can add more files, to make your application more modular. For instance, if you have to add a jQuery-UI custom library, you can add the file to the project :

gapi1

and then, insert this code into the header of the main page :

<?!= HtmlService.createHtmlOutputFromFile(‘jquery_ui’).getContent(); ?>

Bind Google Scripts with Javascript.

Now that we have the static page, let’s see the dinamic part.
Opening the «JavaScript.html» file, we can find this:

gapi2

First of all, we can realize that we’re going to work with a jQuery framework, therefore there is a library link at the top.

Then, we can see the $(function() {}) declaration. As you may know, this is the way (or one of them) to implement the short document onready function in jQuery. That means that it will be executed when the page is loaded in the browser.

So, when our page is loaded in the browser, this javascript will call automaticaly the “google.script.run” method, that binds the javascript client side code with de Google Script in the server.

In order to use this method, we must to declare :

  • getFolderContents: The “Script” function to be called (into the Code.gs file). In this case, we’re going to call the getFolderContents() script function.
  • withSuccesHandler: This is the handler function that will be called after the script function, if all goes ok.
  • withFailureHandler: This is the handler function that will be called after the macro function, if anything goes wrong.

As you can see, if the macro function goes wrong, we’ll load and show the error message into the “error-message” div, giving the apropiate style to it.

Before understanding the succes handler, we must to see how the Google Script.

So, let’s open the Code.gs file again, and look to the getFolderContents() function :

gapi2

This is an easy example about how can we deal with Google Services there. In this case, it is using the Drive App Service, that allows us to work with the Google Drive.

The script gets an initial folder. If we have passed the ID parameter, it uses getFolderById() function, else the getRootFolder() function. Then, it gets the folder file list (with getFiles) and loops its 20 first files, and gets the name of each one (with getName). It loads the list into an array object (contents.children), and returns the object.

Now, into the Javascript client side, if the macro ended ok, the updateDisplay function will be executed.

gapi2

This function collect the result array into the contents parameter, and loads the list into the page with a simple loop and some dynamic html construction.

Developing a new version

Now that we have seen how the script works, we’re going to add some new code to the example, in order to understand it a little bit better.

For example, we will add a button to create a new folder. This is not complicated.

First, we add a submit input into the HTML main page :

<input type=”submit” id=”id_add_folder_button” value=”ADD NEW FOLDER”/>

and in our init javascript function, we link a function to call when it’s clicked:

$(function() {
    $(‘#id_add_folder_button’).click(fun_add_folder);
    …
}

In the fun_add_folder javascript function, we have to call a new Google Script (addFolder) :

function fun_add_folder() {
    var fname = prompt(“Folder name:”, “New folder”);
    if ((fname != null) && (fname != ”)) {
       $(‘#id_add_folder_button’).attr(‘disabled’, ‘true’);
       google.script.run
          .withSuccessHandler(function() {
             $(‘#id_add_folder_button’).removeAttr(‘disabled’)
          })
          .withFailureHandler(function(msg) {
             $(‘#error-message’).text(msg).addClass(“error”).show();
$(‘#id_add_folder_button’).removeAttr(‘disabled’)
          })
          .addFolder(folderId, fname);
    }
}

In order to avoid parallel requests, note that just after calling the function, the button turns disabled, and after executing the Google Script it turns on again. This is not the best way to prevent multiple calls at the same time, but it is helpful show the user that he shouldn’t click again the button until the answer.

In the Code.gs file, we must code the addFolder function as :

function addFolder(folderId, folder_name) {
    if (folderId == ‘root’) Current_Folder = DriveApp.getRootFolder();
    else                    Current_Folder = DriveApp.getFolderById(folderId);
    Current_Folder.createFolder(folder_name);
}

In this case, we have 2 input parameters (the folder parent ID, and the new folder name), and none for return.

We can create a new folder as easily as with calling the createFolder() function.

Now, we can try our new version with launching the /dev URL. However, this must be a provisional URL, to try the App while we’re developing. If we try to use the /exec URL, we will not see the changes, because before that, we must publish the new version of the Web App.

To get it, we must go to “Publish” – “Deploy as web app…”, and then choose a “New” Project version. It is advised to write a comment about the changes.

gapi2

And finally, updating the project version we can use the /exec URL as well.

Categories:Uncategorized

How to set up ASUS BIOS to boot from USB

Sometimes things that must be easy, are not.

When I bought my ASUS laptop, the first I did was install my GNU Linux OS. However, my first deal was find out how to boot my new computer from a USB drive, in order to launch the instalator. But, making my life worst, I realized that ASUS’ BIOS is not so easy to understand. But finally, after following this steps below I managed to boot my laptop from an USB key.

First of all, we have a very simple way to select the boot device: Pressing the “ESC” key immediately when the computer turns on. In this case, the system shows us a little list, with the different choices of the devices and options you can boot. If your USB is in the list, that’s perfect. You only have to choose it, and that’s all.

2015-09-23 12.43.13

 

However, in my case the USB was not in this list (may the easy way be the most frequent!).

To solve it I had to enter in the BIOS setup, by pressing the “F2” key immediately when the computer turns on. For my surprise, the USB boot option did not appear in the boot list either. After several investigations, I learnt that, to enable the option, we must :

  1. Keep a valid USB key connected to the computer (this may seem fool, but it is very important, because if not, you will never see the option in the BIOS).
    BIOS1

  2. In the “Security” tab, select the “Secure Boot Menu”, and mark the “Secure Boot Control” option as [Disabled].
    BIOS2

  3. In the “Boot” tab, mark the “Fast Boot” option as [Disabled], and “Launch CSM” option to [Enable].
    BIOS3

  4. Save the changes, exit BIOS, and enter again.

When you enter again into the BIOS, in the “Boot” tab you should see the USB option in the “Boot Option Priorities” list. Even, you should also see the “Hard Drive BBS Priorities” option, below the “Boot Option Priorities” list :

BIOS4

If the USB drive is not which you need, you can change the origin with the “Hard Drive BBS Priorities” option.

Further more, if you want to set the exactly file from the boot device that have to run, you could use the “Add New Boot Option”. Here there is a menu where you can select the .EFI file (into each device) that you wish select as the initialization file.

BIOS5

 

 

Categories:Uncategorized

How to add dictionaries into an eBook reader

One of the most important ways to learn languages is by book readings. Making this work easier, there’s a powerful tool to help us: the eBook readers with inlaid dictionaries. So I’m going to explain how I did it.

First of all, you have to install Moon+ Reader (the most popular eBooks reader app) on your device. There’s a free version (with some advertisement), or if you want, you can buy the pro version (it is a little bit expensive, more than 5€ :-/ too much for me). Twice works, it doesn’t matter.
Then, open the app, and import a eBook. For example, I’m going to use one of my favourites: Robinson Crusoe :
2015-04-28 21.33.02
Open the eBook, and tap (with a long press, about 1 or 2 seconds) any word of the text. This would open the dictionary with the information of the word, but so far (in the first time) it will show you that message, because there’s no dictionary app installed :
2015-04-28 21.08.21
At this point, you have to install one Dictionary App. We’re going to install “ColorDict” app.
Press ok in the message, and it will redirect automatically to the app market to install the “ColorDict” dictionary app. Accept it, and wait the installation.
2015-04-28 21.09.47
When the installation finished, open ColorDict App.
In this app, you can add as many dictionaries as you want. For example, the wikipedia reference, the english/spanish translation, english irregular forms, and others. You can show a list of available dictionaries in the app Market by click on “Download Dictionaries” :
2015-04-28 21.11.52
Every dictionary is embedded in an another app in the Market.
In my case, I’ve installed the “English Irregular Forms Dict” (for irregular forms), “English Dictionary Wordnet” (for general word information), “Spanish English Dictionary” (for spanish translations) and “English Thesaurus Dictionary” (for synonyms).
To install them, you have to install each of those apps. Open it (each app you have installed), and this will automatically add the data dictionary into the ColorDict app. Then, you can uninstall every Data dictionary apps, because the data were included yet, and you don’t need the app anymore :
2015-04-28 22.01.03b
Now, if you open the ColorDict app again, you will see the list of installed dictionaries. Here you can disable the dictionaries you don’t want to use, and order the available dictionaries in the way you want to show the information. For example, I prefer to see the irregular forms info at top, continued by the Wordnet info, and then the Spanish translation info. So I’m going to order my list in that way :
2015-04-28 22.29.46
You can use the ColorDict app directly, by typing the searching word there. But the powerful way to use that is in the eBook reader.
Now, by tapping (with a long press) a word you don’t understand, directly into the eBook reader, the dictionaries entries will be shown over the text to help you read easier, faster, and better :
 2015-04-28 22.32.43
Enjoy it!
Categories:Uncategorized
Enfilant el camí

Visualitzant el present per construir el futur

El Noguer

Visualitzant el present per construir el futur

Visualitzant el present per construir el futur