11 mai 2012

Google Application Engine si GQL

Google Application Engine este o platforma pentru deployment-ul unor aplicatii web scrise in mai multe limbaje de programare (gen JSP, Python, Ruby). Este usor de instalat, de rulat, e gratuit in limita a 1GB de date, ofera acces la un Datastore, iar pentru Python ofera un framework numit webapp care usureaza construirea aplicatiilor. (descrierea nu se opreste aici)

GQL - este un limbaj asemanator SQL folosit in GAE care insa suporta un singur tip de query : "select [parametri]" - acesta returneaza o liste de obiecte de tipul tabelului considerat. GQL nu este o baza de date relationala, adica nu suporta JOIN-uri, interogarea a mai mult de un tabel/query, iar in campul where din select se poate pune o singura coloana (din motive de rapiditate). In schimb, coloanele nu sunt fixate: pot exista oricate si chiar pot fi schimbate de-a lungul programului.

De exemplu: pentru definirea unui tabel in Datastore mai intai se construieste o clasa al carei nume va fi numele tabelului, cu variabile reprezentand campurile acestuia si tipurile lor.
from google.appengine.ext import db
class User (db.Model):
    username = db.StringProperty (required = True)
    password = db.StringProperty (required = True)
    email = db.StringProperty (required = False)
Crearea clasei User este echivalenta cu crearea tabelului in baza de date (acest lucru este specificat de db.Model care reprezinta clasa mostenita).
Oriunde in program, se poate crea acum un obiect de tip User pe care sa il inseram in baza de date:
u = User(username = "boom", password = "ble", email = "bee@gmail.com")
u.put()
Tabelul User, la fel ca orice tabel din GQL, contine un camp suplimentar numit id ca o cheie primara, generat automat. Daca vrem sa aflam id-ul inregistrarii ce tocmai am inserat-o, se foloseste:
id = u.key().id()
Consultarea tabelului User se poate realiza foarte simplu:
entries=db.GqlQuery("select * from User")
for entry in entries:
    self.response.out.write(entry.username + " " + entry.email)
"entries" furnizat este o lista de obiecte de tip User, si campurile fiecarui User se acceseaza cu "."
Pentru stergerea unei inregistrari se poate folosi:
db.delete(entry)
, unde entry este un element din entries (lista returnata de select).

13 aprilie 2012

Exemplu simplu AJAX + php (metoda GET)

  AJAX (Asynchronous JavaScript and XML) se ocupa cu schimbul unei cantitati mici de informatii cu serverul al unei pagini web, in fundal, fara sa fie nevoie de reincarcarea intregii pagini pentru a obtine informatiile necesare.

  Un exemplu simplu: utilizatorul introduce o parola intr-un textbox si primeste instant un feedback privind puterea parolei sale. Am considerat ca o parola slaba inseamna mai putin de 5 caractere, una medie cu mai mai mult de 5 caractere, fara numere, si una puternica o parola ce contine peste 5 caractere din care cel putin unul este o cifra (evident in realitate nu este asa).





---------------------------- index.html --------------------------------------------

<html>
<head>
<script type="text/javascript">
function getStrength(input) {
var request;
var str;
if (input.length<5) { 
  document.getElementById("strength").innerHTML= 'slaba';
  return;
  }
// code for IE7+, Firefox, Chrome, Opera, Safari
  request = new XMLHttpRequest();
request.onreadystatechange=function() {
  if (request.readyState==4 && request.status==200)
        document.getElementById("strength").innerHTML=request.responseText;
  }
request.open("GET","script.php?data="+input,true); // async
request.send();
}
</script>
</head>
<body>

<form action="">
Parola: <input type="text" id="txt1" onKeyUp="getStrength(this.value)" />
</form>
<p>Putere: <font color="#009900"><span id="strength"></span></font></p>

</body>
</html>

---------------------------- script.php --------------------------------------------


<?php

if (isset($_GET['data'])) {
$pass =  $_GET['data'];
$response = 'medie';
if (preg_match('#[0-9]#',$pass)) {
$response = 'puternica';
}
echo $response;
}

?>

----------------------------------------------------------------------------------------

Dacă am fi folosit metoda POST în loc de GET, atunci ar fi fost obligatoriu trimiterea a cel puțin 2 antete: Content-Type și Content-length - folosind metoda setRequestHeader pe obiectul request, iar în send să fie trimis ca parametru obiectul de date (format JSON, xml, etc). 

07 aprilie 2012

Functii in javascript

<script type="text/javascript">
// crearea unui obiect myObject: contine o variabila value si o functie increment
var myObject = {
value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};

myObject.increment();
console.log(myObject.value);    // 1

myObject.increment(2);
console.log(myObject.value);    // 3

 // adaugarea unei noi functii obiectului nostru numita double
myObject.double = function () {
    // functia nu e buna
var wrongHelper = function () {
this.value = this.value + this.value;
};
 
wrongHelper();

  // functia este buna
var rightHelper = function () {
myObject.value = myObject.value + myObject.value;
};
 
rightHelper();
};

// Invoke double as a method.
myObject.double();
console.log(myObject.value);    // 3
</script>


Prima metodă din double (wrongHelper) este greșită deoarece this.value nu este definit. Mai precis this nu referă obiectul curent reprezentat de myObject, ci se află într-o funcție care la rândul ei este într-o funcție și contextul este reprezentat de acea funcție care o conține. Pentru a rezolva acest lucru, în rightHelper am înlocuit this cu myObject.

05 aprilie 2012

Backtracking si partitionarea unui numar in Python


nsol = 0.
nz = 0.
nr = []
N = 0.

def construct(nr_partitii, numar):
    global N, nr
    N = numar
    for i in range(nr_partitii):
        nr.append(0)

def is_zero():
    for i in range (len(nr)):
        if nr[i] == 0:
            return True
    return False

def init (k):
    nr[k] = -1

def succesor (k):
    if nr[k] < N:
        nr[k] += 1
        return True
    nr[k] -= 1
    return False

def valid (k):
    suma = 0.
    for i in range (k):
        suma += nr[i]
    if suma+nr[k] <= N:
        return True
    return False

def solutie (k):
    return k == len(nr)-1 and sum(nr)==N

def bt (k):
    init(k)
    global nsol, nz
    while succesor(k):
        if valid(k):
            if solutie(k):
                #print nr
                nsol += 1
                if is_zero():
                    #print nr
                    nz += 1
            elif k<len(nr)-1:
                bt(k+1)

print "Partitionarea unui numar"

construct(4,12)
bt(0)

print "Solutii: ",nsol
print nsol-nz,"combinatii de termeni nenuli"

Probabilistic Robotics

"Probabilistic Robotics" - Sebastian Thrun, Dieter Fox, Wolfram Burgard
Acest ebook este suport de curs pt multe cursuri de robotica, si recomandata ca further reading pentru Udacity cs373.
P.S. acesta este un draft din anul 2000. Cartea finală a apărut în 2005 dar nu se găsește la liber pe internet. Ea conține în mare aceleași capitole cu unele modificări și adăugiri (cum ar fi Graph SLAM).