Sunday, December 15, 2013

A Christmas Gift to Myself : Raspberry Pi


Here are some ideas me and my friend Mohit are going to implement when our Raspberry Pi's reach us -

  1. Personal search engine : I have a big collection of ebooks and publications I constantly need to query. So, putting its search index on a webserver would make it accessible to me everywhere and thus fasten up my research quite a lot. I'm going to use recoll for the PSE.
  2. Bit Torrent Sync - Personal data back-up server.
  3. Social network data mining - Using facebook and gmail API this could be easily implemented. Although, I need to find more open source algorithms to run. I am also open to implementing research algorithm [1]. Looking for suggestions here.
  4. Mint Server (mint.com) - My bank sends me alerts after every successful transaction. This makes it easy to implement my own mint.com server and also a splitwise.com.
  5. Bitcoin mining 
  6. Tor server - This was Mohit's idea. This reminds me of  Oscar Wilde's quote.
  7. A personal home music server (Mohit's idea)
  8. A live twitter feed monitoring and LED lighting - something on these lines.

I'm also going to get a Raspberry Pi camera module. It would be nice to create a compressed time-lapse video. I need more suggestions here too.

PS : comments and suggestions required.




Friday, December 13, 2013

Hacking Dropbox

Having spent a lot of time finding tools for file syncing without a cloud and those that would work behind proxies, I decided to write my own Dropbox app to synchronize data across computers.

But Dropbox already does that. The point is to be able to do that using the free 2GB space that Dropbox provides. The motivation is that this way the synchronization should work behind every network routers (which must not block dropbox) that blocks torrent data. (ofcourse you can also avoid that using SSH tunneling).

So I decided to register a Dropbox developer app and use the Dropbox API to synchronize files using only the free 2GB storage. The only constraint now is that the individual files cannot be more than 2GB, but that is easily solved by breaking up the file using rar. Note that, the same could be done using Google Drive which provides 15GB of free space.

The Dropbox API documentation is very neat. I used the core Dropbox API with full access to user data for this app. The code below just authenticates the app to allow access to the user account. Once provided the authentication is then saved to a file, which when detected is used again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import dropbox
import email, imaplib, os
import urllib2

##sign in to DROPBOX
app_key = '<key>'
app_secret = '<secret>'

flow = dropbox.client.DropboxOAuth2FlowNoRedirect(app_key, app_secret)
app_auth = False # set to false initially
if os.path.exists('accesstoken'):
 app_auth = True

if (app_auth == False):
 ### authorize server
 authorize_url = flow.start()
 print '1. Go to: ' + authorize_url
 print '2. Click "Allow" (you might have to log in first)'
 print '3. Copy the authorization code.'
 code = raw_input("Enter the authorization code here: ").strip()
 access_token, user_id = flow.finish(code)
 ## save access token once
 f = open( 'accesstoken', 'w' )
 f.write( access_token )
 f.close()
else:
 f = open( 'accesstoken', 'r' )
 access_token = f.read()
 f.close()

client = dropbox.client.DropboxClient(access_token)
print 'linked account: ', client.account_info()


The server and client communicate uses gmail. When the server uploads a file it emails the client the share link for the data. The client continuously monitors it's mailbox. As soon as it receives an email from the server, it downloads the data and sends back an acknowledgement mail. The server receives the acknowledgement, deletes the previous file, uploads another and sends the share link to the client again.


1
2
3
4
5
6
7
8
##sign in to GMAIL
user = "<server>"
pwd = "<password>"

m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.list()
m.select("inbox")


Here's how I implemented the rest of it (thanks to these webpages 1, 2, 3) . The script for the client side would be similar

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
##main for loop
while True:
 resp, items = m.search(None, 'TO', '"<server>+python@gmail.com"')
 items = items[0].split()
 print items

 emailid=items[-1]
 resp, data = m.fetch(emailid, "(RFC822)")
 email_body = data[0][1]
 mail = email.message_from_string(email_body)

 if mail['Subject'] == "done"
  ##delete file
  client.file_delete('/'+os.path.basename(uploadfilepath))
  
  ##ask for another file (or just read from a file list) to upload directory in dropbox = main
  uploadfilepath = raw_input("enter (absolute) path to file").strip()
  uploadfile = open(uploadfilepath)
  response = client.put_file('/'+os.path.basename(uploadfilepath), uploadfile)
  print "uploaded:", response

  ##create share link
  sharelink = client.share("/"+os.path.basename(uploadfilepath), False)
  print sharelink['url']+"   "+sharelink['expires']

  ##send email
  from send_email import mail
  mail("client+python@gmail.com",   sharelink['url'],    "")
  print "email sent"
  
 time.sleep(25000)


The send_email script called above is the following :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os

gmail_user = "<id>@gmail.com"
gmail_pwd = "<passwd>"

def mail(to, subject, text):
 msg = MIMEMultipart()

 msg['From'] = gmail_user
 msg['To'] = to
 msg['Subject'] = subject

 msg.attach(MIMEText(text))

 #part = MIMEBase('application', 'octet-stream')
 #part.set_payload(open(attach, 'rb').read())
 #Encoders.encode_base64(part)
 #part.add_header('Content-Disposition','attachment; filename="%s"' % os.path.basename(attach))
 #msg.attach(part)

 mailServer = smtplib.SMTP("smtp.gmail.com", 587)
 mailServer.ehlo()
 mailServer.starttls()
 mailServer.ehlo()
 mailServer.login(gmail_user, gmail_pwd)
 mailServer.sendmail(gmail_user, to, msg.as_string())
 # Should be mailServer.quit(), but that crashes...
 mailServer.close()

Wednesday, December 11, 2013

File Sync without the Cloud

I had to share some large data files with a friend recently. As I was going through the list of usual options :
1. Opera Unite
2. Torrent sharing
3. Dropbox
4. Google Drive
5. wetransfer.com
6. justbeamit.com

I found no fast and cheap option. The painful thing about the good (fast) services is that they do not provide only sync across computers, but require you to upload data to their servers, which is both expensive and insecure.

I found an awesome software, Bitsync, that just works on any device. Yes, even my phone running android. No need to setup port forwarding or go through any tech hassles. And the best feature of all, it's FREE. It's also very fast. Usually when I had to resort to torrent-sharing the speed of download was very slow, but bitsync somehow finds the optimal path.

There are other companies that provide the same service. The best among them is aerofs . You wouldn't require it's paid services for most personal use. Here's a list of all such softwares on how-to-geek .



Saturday, November 23, 2013

Counting

Much of information and coding theory involves counting and combinatorial reasoning. For example how many non-touching balls of unit radius can fit  in an n-dimensional space ${\mathcal{F}_2}^n$.  Combinatorial arguments come in very handy in these situations. The probabilistic method is another example of the kind of arguments I came across in information theory literature. One good non-technical example that changed the way I count is -

Q. Consider a group of  $2^6 = 64$ tennis players. These players are now matched pairwise and the losers are eliminated from the pool. From the remaining pool of victors, players are paired again and the process is continued. How many games are required to find a single winner?

A. 63

Method 1. One way (the straightforward method atleast before reading the alternate way) to compute the answer is to count the number of matches in each round i.e. 32 + 16 + 8 + 4 + 2 + 1 = 63.

Method 2. Realize that each match eliminates 1 player, hence to eliminate 63 players you need 63 matches.


Tuesday, November 19, 2013

Interesting Arguments


An interesting line of reasoning that I came across in my Combinatorial Theory  course is
the minimal element method.

The general outline of a proof using this method is as follows : Suppose you want to prove that a given set of elements satisfy a given property $P$. Let the set of bad elements not satisfying that property be denoted by $\mathcal{B}$. Assume that $b$ is the minimal element of $\mathcal{B}$ in some sense. Then using the assumptions of the claim, show that there exists  another element $b^\prime \in \mathcal{B}$ such that $b^\prime < b$.

Another interesting style of argumentation which is generally seen in information theoretic arguments is the probabilistic method in which a deterministic solution to a given problem is shown to exist by constructing a random candidate for a solution, and showing that this candidate solves all the requirements of the problem with positive probability.

Saturday, October 26, 2013

Typesetting math equations in Latex

While writing any document in $\LaTeX$ using the amsmath package many wishes need to fullfilled. The most cumbersome task that troubles me frequently is typing the right and left delimitors (say \lvert \rvert) seperately. Why can't there be a command that does that on its own. Turns  out that somebody did write a package to improve upon amsmath : mathtools .

The most useful feature I found is, allowing the user to define paired delimitors For example, instead of typing,
    \left\{ \frac{a}{b+c} \right\}
You can just define paired delimitors and use them as follows,
    \usepackage{mathtools}
    \DeclarePairedDelimiter{\set}{\lbrace}{\rbrace}
    \set*{ \frac{a}{b+c} }
The output is the same as before,
$$\left\{ \frac{a}{b+c} \right\}$$

Using the * after the command resizes the delimitors to fit the vertical length of the expression.

Another interesting tool in this package is allowing tags for equations to have user-defined labels. See section 3.2.2 in  mathtools .

Another great tool for publishing documents on the web is mathjax. Recently mathjax allowed users to use mathjax scripts through their plugins on popular web platforms. 

Wednesday, October 23, 2013

Subadditivity, Limits and Lim Inf

Consider a sub-additive sequence $a_n$ for $n \geq 1$, where sub-additivity is defined as follows :
$$a_{n+m} \leq a_n + a_m$$

Fekete's Lemma says that for any such sequence $\lim_{n \rightarrow \infty} a_n/n = \lim \inf_{n \rightarrow \infty} a_n/n $, which can be easily proved. The proof is as follows-

Let $\lim \inf_{n \rightarrow \infty} a_n/n  = l$. Therefore, $\exists K$ s.t.
$$\left\vert \frac{a_K}{K} - l \right\vert = \epsilon/2$$

Now consider a large enough $L$ such that $ \frac{a_r}{KL} < \epsilon/2, \forall  r < K$. Thus, for every $n \geq KL$ we can write $n$ as $n = Kq + r$, where $q \geq L$ and $r<K$. Therefore,

\begin{align}
\frac{a_n}{n} & \leq \frac{q a_K}{Kq+r} + \frac{a_r}{Kq+r} \\
                        & \leq \frac{q a_K}{Kq} + \frac{a_r}{Kq} \\
                        & \leq \frac{a_K}{K} + \frac{a_r}{Kq} \\
                        & \leq  l + \frac{\epsilon}{2} + \frac{\epsilon}{2}\\
\end{align}

Since this is true for all $n > KL$ the limit exists and is equal to $l$. An alternate but similar proof is given here.