You can find the full project here:
In Costa Rica there's a lack of mechanisms that promote commertial competition and that allows consumers to compare prices between products in an easy and generalized way, in order to make an eficient and smart purchase.
That's why our project is focused in creating a software with the purpose of improving the efficiency of the user's shopping. This will be useful for users with access to internet through their computers or mobile devices.
It also aims to extend the results to facilitate consumers the use of this program and generate them more utilities that depend on aspects such as the user's location, in order to increase the efficiency of the shopping time and its economic cost. Therefore, with this in mind we have work in researching the components that the software will need, for a later development.
It will be implemented what have been done on a first project, in terms of databases and multi-process servers to create different interfaces and complete the server code. This by using two programming languages, python and java.
For the last we want to implement the interface to an application in Android, so it's relevant to know and research about Android development environments, and the creation of apps.
All this in order, to give people a complete tool that allows to increase competitiveness and improve the conditions for consumers from the wide range of offers in the market.
General Objective:
Specific Objectives:
To achieve our objectives, we needed to create databases and servers. For the databases we used MYSQL ( My Structured Query Language 1) ) as our database management system 2).
MySQL is a client / server system that consists of a multi-threaded SQL server, multiple client programs and libraries, administrative tools, and a variety of programming interfaces (APIs). Can also be obtained as a multithreaded library that can be linked into other applications to obtain a smaller, faster, and easier to handle product. And it's server is widely used, very fast, safe, and easy to use. And it has different connectors to JAVA, PYTHON, C, C++, PHP, ODBC and .NET .
In order to create our database and server, we needed to learn how to create them and make them work, that's why we created a tutorial that is divided in two parts: First, you'll find a tutorial for creating databases in MYSQL, and controlling them through python. Later you'll find a tutorial for creating a server with multi-process and how to specify it's communication protocol.
As it was exposed previously, the purpose of developing this project is help the users by improving the efficiency of their shopping. By providing them an aplication in which they are able to sign up; check up, seek and add items by scanning barcodes, also they can edit the information of added items. Users will be able to create and save lists with the products they are looking for, and the application will provide them a list with the recommended establishment, the cheapest and the closest, where they can do their shopping; including the price and place to every item.
In order to achieve that and give a better perception of the application's idea, we have proposed the following flowchart.
For our proyect we need to create a database, in order to record: users, items, stores, shopping lists, and it's relations 3).
With this in mind, we decided to create several tables, that will contain this information, in this way:
Contains each user's: username, password, name, email, privileges, and number of submits.
Contains each item's: barcode, name, brand, quantity, description and an image.
Contains each store's: id (a number), name, latitude, longitude, location.
Also, there are tables for the relations between the previous tables:
Contains each list's: id (is a number, ascending), username (to whom it belongs), and it's name (the name by which the user recognizes it).
Contains the relation between items barcode and the list-id to which it belongs.
Contains the relations between: each item's barcode, the store id, and the price of that item in that store.
We'll explain each table and the way we controlled the whole database through python, in here:
For more detailed information about the development of this server check out this page: Writing a multi-process server with python
The server main function will run two functions: the first creates and configures the socket as a server and the second is an infinite loop. Inside this loop the socket will be expecting new connections, once it's achieved it does a fork and then creates an instance of client_server class.
The object client_sver is in charge of answering all the client requests. To manipulate the database it uses the DBmethods file. The constructor of the object receives the socket created after the establishment of communication between server and client.
Once the client_server object has been created the function decide is called. This is another infinite loop in charge of receiving all the client request and detecting which is the function that must be executed. The last non specific function is answer() and its work is to inform the client if the work over the database was successful.
The next file are the server and client_server code, further a more user friendly version of the network client.
#! /usr/bin/env python import socket, os import client_server from client_server import Client_server def socket_setup(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('192.168.1.103', 10101) server.bind(server_address) server.listen(1) print "server created and configured" return server def wait_connection(server): wait_connection = True while wait_connection: print "Online and waiting for new requests" client_socket, client_address = server.accept() newproc = os.fork() if newproc == 0: wait_connection = False client_sver = Client_server(client_socket) client_sver.decide() client_sver = None print 'lost connection' os._exit(1) def main(): server = socket_setup() wait_connection(server) if __name__== "__main__": main()
# /usr/bin/env python import socket import DBmethods as dbm class Client_server: def __init__(self, client_socket): self.client_socket = client_socket def __del__(self): del self.client_socket def decide(self): self.client_socket.settimeout(900) while True: try: msg = self.client_socket.recv(4096) except socket.timeout: self.client_socket.close() break instruction = [] instruction = msg.split('<>') command = instruction[0] if command == 'printf': self.printf(instruction) elif command == 'add_user': self.add_user(instruction) def answer(self, status): if int(status): answer = 'Success' else: answer = 'An error has ocurred' self.client_socket.sendall(answer) def printf(self, msg_list): print msg_list[1] self.answer(1) def add_user(self, msg_list): # write_user(username, password, name, email) status = dbm.write_user(msg_list[1], msg_list[2], msg_list[3],msg_list[4]) self.answer(status)
#! /usr/bin/env python import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('192.168.12.199', 10100) print "socket created" client.connect(server_address) print "connection established, write a command" def ask_info(): info = raw_input() return info print '/n' exit = False while not exit: command = ask_info() if command == "exit": exit = True elif command == 'print': info = ask_info() message = 'printf<>'+info client.sendall(message) print client.recv(10) elif command == "add_user": tmplist = ['username', 'password', 'name', 'mail'] j = 0 for i in tmplist: print i, tmplist[j] = ask_info() j += 1 info = reduce(lambda x,y: x+'<>'+y, tmplist) message = command+'<>'+info client.sendall(message) print client.recv(10) # check if the operation succeded
The communication protocol is a way to synchronize the work made in the client with the one in the server. It is pretty to understand if you follow the functios with the flowchart in mind. The idea is to foresee all the functions that must to be implemented in server and client as well.
The next file is the implementation of this idea.
#This is not a program!! we used the py extension for syntax highlight only. #comunication protocol between the server (s) and the client (c) #login *c-s: login<>username<>password *s-c: login<>success || login<>invalid username/password combination #sing up *c-s: signup<>username<>password<>realname<>email *s-c: signup<>succesful || signup<>invalid username #item check up *c-s: seekitem<>barcode<>latitude%/longitude #item found *s-c: seekitem<>name<>brand<>quantity<>description<>image<>lowestprice<>lowestprice_store<>closestlowerprice<>closestlowerprice_store #edit item *look below #item not found *s-c: seekitem<>notfound #submit a new item *look below #edit item // submit a new item #look for current store *c-s: storeinratio<>latitude%/longitude *s-c: storeinratio<>storeinratio_1%/storeid<>.... #client didn't find the store *c-s: addstore<>name<>location<>latitude%/longitude *s-c: addstore<>succes<>storeid || addstore<>data base error *c-s: edititem<>barcode<>name<>brand<>quantity<>descripton<>image<>price<>storeid #if it is a submit then submititem<>barcode.... *s-c: edititem<>success || submititem<>success #add the item to list look below # add item to list *c-s: requestlists *s-c: requestlists<>"list#1"%/"list#2"%/... #new list *c-s: newlist<>listname *s-c: newlist<>succesful #delete list *c-s: delist<>listname *s-c: delist<>succesful *c-s: addtolist<>listname<>barcode #remove item from list delfromlist<>listname<>barcode *s-c: addtolist<>succesful # way to shop! *c-s: requestlists *s-c: requestlists<>"list#1"%/"list#2"%/... #new list *look above (in add item to list) #list selected c-s: listitems<>listname s-c: listitems<>item1%/item2%/... # I DON'T KNOW WHAT TO DO IN "ADD" BUTTON #save list c-s: savelist<>listname<>item1%/item2%/.... #way to shop look below #way to shop c-s: waytoshop<>savemytime<>listname s-c: waytoshop<>savemytime<>place1/*\totalprice/*\tem1%\item2%\item3....[]place2/*\totalprice/*\tem1%\item2%\item3....[].... #similar way for savemymoney
Normally the instructions and the into are separated by <> but in some cases you even need to split that part of the message, this is why some communications uses /\ and [] to split some internal messages.
The explanation above was just a brief demonstration of Way To Shop server. For many reader this maybe enough, but if you are interested in the full server implementation click the next link:
The development of mobile applications for Android is usually done using Java as the programming language. Pythonists may not know that since June 2009 it is possible to write applications for Android in Python using SL4A (Scripting Layer For Android).
The SL4A allows developers to edit, run scripts and interact with interpreters directly on the Android device. These scripts have access to many of the APIs of the operating system (OS), but with a greatly simplified interface that makes it easy to:
Between other functions. This project was started by Damon Kohler [] and, like most of Android, SL4A is open-source and distributed under the Apache 2.0 license. SL4A also supports other languages like Beanshell, JRuby, Lua, Perl and Rhino. But in this tutorial we only use Python SL4A.
You'll see that the Python For Android, for the SL4A is just like the one on a PC, and it supports different modules from the standard library, like: glob, httplib, math, os, pickle, shlex, shutil, ssl, string, subprocess, sys, tempfile, time, thread, unittest, urllib, uuid, xml . Even the Zen of Python from Tim Peters. There are modules like the gdata with which you can have access to Google interface services, like creating and editing spreadsheets.
There are also some libraries for using the bluetooth (PyBluez), the red engine, based on events (Twisted), and for astrological data (pyEphem), and lately the PyGame library has been supported!.
There's also a way to use other modules, by adding them on the folder /sdcard/com.googlecode.pythonforandroid/extras/python . So you can use them as if they were part of the standard library.
In this tutorial you'll learn to set your Development Environment, set up a emulator, install SL4A and a basic tutorial for developing App's (GUI's and basic commands).
For installing the SDK go to:
And follow the steps to get the Android SDK for linux, download it from here:
After downloaded it, it's necessary to extract the files from it. Go to the tools folder and open the executable file “Android”. Select and install the following packages:
After installing the Android SDK for Android, the emulator is ready to be launched. When it is launched it's necessary to install the SL4A & Python on the Android Emulator following these steps:
You can see a tutorial to install the SL4A & Python on Android Emulator on this video:
Installation of SL4A & Python on Android Emulator
The first problem you may find when you have the scripting layer for android, is that you may need to write the scripts directly from your cellphone or the emulator, this is not appropriate for developing long and quick apps.
Actually you can write the scripts and upload them to your phone or emulator in several ways, one way is writing the script in your computer and generate a QR code with it. For this go to: QR Code Generator from the ZXing Project and select a text content, then in the first line write the name of your python file (“example.py”) then paste your code. This will generate a QRcode. Now in your cellphone, open the SL4A app, press the Menu key, then Add, then select the option “Scan Barcode”.
This option is only helpful if your code is not very extensive, otherwise you won't be able to generate a QR code. There's other option using the Android Debug Bridge, that's in the Android SDK. This file is located in the android-sdk/platform-tools folder, to facilitate its use, include the folder in your $PATH (.bash_profile).
After this, connect your cellphone to your computer with a USB cable (with an emulator this step is clearly not needed). Then you'll be able to send files to your cellphone or emulator with the terminal by doing this command:
$ adb wait-for-device $ adb push myscript.py /sdcard/sl4a/scripts
There's other options for uploading scripts, like Remote Control using the server support, or using ssh, by email, and other way's that would not be explained in this tutorial.
As you can imagine, programming apps in python its really simple, here we are gonna explain a few basic commands, but you can see the full API Rererence here.
The first thing to do its to import the Android library
import android droid = android.Android()
After this, the app can go anywhere and anyway you want it to, just like a regular script. But there's a few interesting commands we would like to emphasize in. For example the makeToast command, its a simple way to show a little message.
droid.makeToast("Hellow World!")
There are a lot of things that are really useful and simply to do in the SL4A. For example, a barcode scaner app, that uses the Zxing Barcode Scanner App (Needs to be installed).
#We scan the barcode code = droid.scanBarcode() #Extract the code barcode = code[1]['extras']['SCAN_RESULT']
Also, you can do things like getting the GPS coordinates in a few lines!
#We start locating the client droid.startLocating() time.sleep(10) location = droid.readLocation().result #In case that the location failed, we get the last known location if (location == {}): location = droid.getLastKnownLocation().result #When we already have one known location if (location != {}): try: result = location['gps'] except: result = location['network'] #We extract the latitude and longitude from the lecture latitude = result['latitude'] longitude = result['longitude'] #If your country is supported, you can get an address from the geocode proyect address = droid.geocode(latitude, longitude).result #We stop locating droid.stopLocating()
There are a few graphical resources, especially dialogs. You can create a loading dialog
#We start a loading alert droid.dialogCreateSpinnerProgress("Loading", "Please Wait") droid.dialogShow()
You can create an alert box or a question and respond to id 4).
droid.dialogCreateAlert("I like swords.","Do you like swords?") droid.dialogSetPositiveButtonText("Yes") droid.dialogSetNegativeButtonText("No") droid.dialogShow() response=droid.dialogGetResponse().result droid.dialogDismiss() if response.has_key("which"): result=response["which"] if result=="positive": print "Yay! I like swords too!" elif result=="negative": print "Oh. How sad." elif response.has_key("canceled"): # Yes, I know it's mispelled. print "You can't even make up your mind?" else: print "Unknown response=",response
The print command just prints in the terminal, just like in a computer.
The Android Scripting Layer doesn't have a real graphical support, therefore we need to seek alternative ways to develop a GUI (Graphical User Interface), PySide is really good option for developing Android Apps GUI. PySide is a Python binding of the cross-platform GUI toolkit Qt. It is one of the alternatives for GUI programming in Python to Tkinter, which is bundled with Python.
Another option for developing a GUI for your application is using the XML code for writing layout's for your app, and them use them in your code. A really easy way of getting the XML code for a layout is building the layout in with the Eclipse + ADT pluggin (The oficial IDE for android), you can get it in the official Android page.
What we'll use will be the full screen interface, that is a new, experimental feature that allows you to define and display a Layout, and respond to button clicks and other key events. This feature is available with the r5 release of the SL4A.
For this, you must create the layout you want in XML code, and the use the droid.fullShow() comand to display it. And trigger an event loop decider in order to react to the events. You can use the droid.fullQuery() or droid.fullQueryDetail() functions to access information from the screen. Also you can use the droid.fullSetProperty() function to change things in the screen. For more information visit FullScreenUI Tutorial Like this:
def eventloop(): while True: event=droid.eventWait().result print event if event["name"]=="click": id=event["data"]["id"] if id=="button3": return elif id=="button2": droid.fullSetProperty("editText1","text","OK has been pressed") elif id=="button1": droid.fullSetProperty("textView1","text","Other stuff here") print droid.fullSetProperty("background","backgroundColor","0xff7f0000") elif event["name"]=="screen": if event["data"]=="destroy": return layout="""<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff000000"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/linearLayout1"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test 1"></Button> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Ok"></Button> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel"></Button> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" android:id="@+id/textView1" android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center_vertical|center_horizontal|center"></TextView> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText1" android:tag="Tag Me" android:inputType="textCapWords|textPhonetic|number"> <requestFocus></requestFocus> </EditText> <CheckBox android:layout_height="wrap_content" android:id="@+id/checkBox1" android:layout_width="234dp" android:text="Howdy, neighbors." android:checked="true"></CheckBox> </LinearLayout> """ print layout print droid.fullShow(layout) eventloop() print droid.fullQuery() print "Data entered =",droid.fullQueryDetail("editText1").result droid.fullDismiss()
If you've followed this tutorial, then you now know how to develop simple scripts and run them in your phone, now we'll explain our client for android of the Way To Shop application. You can see the explanation of our code in here:
Android applications are typically distributed in a single file or package with an .apk extension. An Android package is essentially an archive file similar to a .jar or .zip file. To package our application it's necessary to use Eclipse (a multi-language Integrated Development Environment).
The first thing to do is download the script template file from the SL4A project site (http://android-scripting.googlecode.com/hg/android/script_for_android_template.zip).
Next, make a copy of the template in Eclipse by right-clicking the project and then choosing Copy from the menu.
Next, right-click in an empty area of the Package Explorer window and choose Paste from the menu. Give the new project a name and then click OK. In our case is called WayToShop.
Now comes the part where we insert our script called AndroidScript. Make a copy of the script and paste it into the res/raw directory. The easiest thing to do here is delete the existing script.py file and rename the script to script.py. That way it won’t be necessary to change any of the other locations that reference script.py. You’ll also need to rename the default package com.dummy.fooforandroid/WayToShop.
For that it can be used the Eclipse Refactor/Rename tool to do this. Then it's necessary to update the package property in AndroidManifest.xml to reference WayToShop.
At this point, we're able to go through the build-and-export process to create the WayToShop.apk.