So you wanna move to Canada?

I’ve recently moved to Canada and applied for permanent residency through the Express Entry system. If your situation is similar to me (you have a higher education degree, a few years of part time — yes TA and RA count — or full time experience, you can speak English fair enough) then you might be eligible to enter Canada the same way. To do so, you don’t need to be present in Canada, and you don’t have to remain in Canada the entire time if you don’t think that’s something you’ll want to keep.

There are several ways for moving to Canada, but I know of only one, and I only know a few things about it which is obviously about my case! The way that I applied for immigration to Canada was through the Express Entry process, a somewhat new method which started some time in 2014 I guess. The idea is based on your education, language skills, work experience, age, marital status etc you get a score and enter a pool. Roughly every two weeks the government draws the top people from the pool and invites them to apply for the Express Entry program. That basically means if you have claimed everything correctly, and if you provide all the required documents, and if you have a clean background, then almost surely you’ll get to become a Canadian permanent resident (a five year non-bounding status to live in Canada).

What are your chances to be eligible for Express Entry?

First get a rough estimate of your rating here: http://www.cic.gc.ca/english/immigrate/skilled/crs-tool.asp

Then head over here http://www.cic.gc.ca/english/express-entry/rounds.asp to see the minimum ratings drawn from the pool in the last draw and how others are doing in the pool!

For example, as of my writing, if your score is above 451, andif  in the next round they draw 800 people, you’ll be selected.

What do you need to enter the pool?

Here are the first things you need to do:

  • Take a general IELTS exam at your earliest time. When you are signing up, it asks you what do you need it for, choose for immigration purposes.
  • Evaluate your degrees (all degrees which are not from a Canadian institute). There are a few companies that the Canadian government work with, out of which I only remember WES. Create an account there and fill the forms to tell them what degrees you want to evaluate. Then it will tell you how much you need to pay. After paying it, it will give you a code that you need to keep, and then it will tell you what documents shall you send to them and in what condition. Make sure that the code is mentioned on all the documents.

These are all you need to get into the pool. Do these first and enter the pool as soon as possible. Basically, you claim all the rest and when you get drawn you provide documents to support your claims. So, then start working on the rest of the documents:

  • Work experience. Gather letters from your bosses (preferably your direct supervisors for all the previous jobs, but HR also works) to show your work history. For some countries like Iran you might need to provide your insurance history too. Here is what you need to be in the letter:
    • written on company letterhead,
    • signed by the responsible supervisor,
    • have the printed name and title of the responsible supervisor beneath the signature,
    • show the company’s full address, telephone and fax numbers, e-mail and website addresses,
    • stamped with the company’s official seal (if applicable).
    • the specific period of your employment with the company,
    • the positions you have held during the period of employment and the time spent in each position, and the status of the current positoin
    • main responsibilities and duties in each position,
    • total annual salary plus benefits,
    • the number of hours worked per week

      Your TA and RA also count.  For TA your department head probably is the supervisor. For RA your advisor. Ask them to be very specific about dates, and number of hours, etc. As specific as they can be! Nonetheless all this information is in your contracts.

  • Police records: If you live in US you need one from FBI. At the minimum you want police reports for the countries that you lived in in the past 10 years for at least 6 months. If you need additional reports, they will let you know when you are drawn from the pool.
  • Proof of financial assets: you need about 13000 CND per person in the application. Though per application it might be a different situation. But if that’s the case you need to provide an official letter indicating your financial profile, including
    • list of all your bank (chequing and savings) accounts
    • the account numbers
    • dates each account was opened, and
    • the balance of each account over the past six months,
    • list all outstanding debts, i.e. loans, credit cards, etc,
    • be printed on the letterhead of the financial institution, and include your name and the contact information of the financial institution (address, telephone number and e-mail address).
    • proof of assets, like cars, houses, etc.

     

That’s all for now. I’ll keep adding details here.

Good luck.

 

Miroslav and the separating wand

In a huge graph, it is hard to determine a bottleneck by just looking at it, or doing any type of search. And by a bottleneck, I mean part of graph that is not very much connected to the other part. In different setting this could mean different things, for example, if your graph is a communication network, then a bottleneck mean the information doesn’t get to all of the nodes very easily, there will be traffic around the bottleneck.

images.duckduckgo.comOne of the celebrated results in algebraic graph theory is by Miroslav Fiedler, a Czech mathematician [1, 2], about the algebraic connectivity of a graph. It simply says the second smallest eigenvalue of the Laplacian matrix of a graph determines how connected the graph is. In particular, if it is 0, the graph is disconnected. Furthermore, it shows the eigenvector corresponding to this eigenvalue distinguishes the vertices in the two connected components. In the case that the graph is connected, this eigenvector will find bottlenecks of the graph. Below I first generate a random graph that has a visible bottleneck, then I’ll use Fiedler’s result to find it computationally.

First, let’s generate a random graph with a bottleneck. In order to do so, I’ll generate two random graphs, then I look at their disjoint union and put few random edges between them.

def random_bottleneck_graph(n1,n2,p1,p2,p):
    #n1 = number of vertices of first part
    #n2 = number of vertices of second part
    #p1 = probability of edges of first part
    #p2 = probability of edges of second part
    #p  = probability of edges between two parts
    
    import random
    
    #generate two parts randomly and put them together
    H1 = graphs.RandomGNP(n1,p1) #generate a random GNP graph for first part
    H2 = graphs.RandomGNP(n2,p2) #generate a random GNP graph for second part
    G = H1.disjoint_union(H2) #form the disjoint union of the two parts
    
    #add edges between two parts
    for i in range(n1): #pick each vertex in H1
        for j in range(n2): #pick each vertex in H2
            a = random.random() #generate a random number between 0 and 1
            if a > 1-p: #with probability p add an edge between the two vertices of H1 and H2
                G.add_edge([(0,i),(1,j)])
    return(G)

And here is a sample run:

#initialization
n1 = 40 #number of vertices of first part
n2 = 60 #number of vertices of second part
p1 = .7 #probability of edges of first part
p2 = .6 #probability of edges of second part
p = .01 #probability of edges between two parts

#run
G = random_bottleneck_graph(n1,n2,p1,p2,p)

Of course when I look at the graph, sage who has generated it knows that the graph has two main parts, and even the vertices are numbered in a way that anyone can recognize it. The left picture is generated by the above ‘show’ command, and the right picture is using the following code.

sage0sage1

def show_random_bottleneck_graph(G,layout=None):
    EdgeColors={'red':[], 'blue':[], 'black':[]}

    for e in G.edges():
        if not e[0][0] == e[1][0]:
            EdgeColors['black'].append(e)
        elif e[0][0] == 0:
            EdgeColors['red'].append(e)
        else:
            EdgeColors['blue'].append(e)
            
    G.show(vertex_labels=False,figsize=[10,10],layout=layout,edge_colors=EdgeColors)

So, in order to really get a random graph with a bottleneck, I take the above graph and try to loose the information that I had from it.

def relable_graph(G,part=None):
    # input: a graph G
    # output: if part is not given, it gives a random labeling of nodes of graph with integers
    #         if part is given, then it partitions the vertices of G labeling each vertex with pairs (i,j) where i in the number of partition the vertex is in part, and j is an integer.
    
    V = G.vertices()
    E = G.edges()
    
    H = Graph({})
    
    map = {}
    if part == None:
        new_part = None
        import random
        random.shuffle(V)
        
        for i in range(len(V)):
            map[V[i]] = i
    else:
        new_part = [ [] for p in part]
        count = 0
        for i in range(len(part)):
            for w in part[i]:
                map[w] = (i,w)
                new_part[i].append((i,w))
                count += 1
    
    for v,w,l in E:
        H.add_edge([map[v],map[w],l])

    return(H,new_part)

###############################
#run
H = relable_graph(G)[0]
H.show(layout='circular',vertex_labels=False, figsize=[10,10])

Now if I look at the graph I won’t be able to recognize the bottleneck:

sage3

Now that I truly have random graph, which I know has a visible bottleneck, let’s see if we can find it. Below I use ‘networkx’ to compute the Fiedler vector, an eigenvector corresponding to the second smallest eigenvalue of the Laplacian matrix. Then I’ll partition the vertices according to the sign of the corresponding entry on this vector:

def partition_with_fiedler(G):
    # input: a graph G
    # algorithm: using networkx finds the fiedler vector of G
    # a partitioning of vertices into two pieces according to positive and negative entries of the Fiedler vector
    
    import networkx
    H = G.networkx_graph()
    f = networkx.fiedler_vector(H, method='lanczos')
    
    V = H.nodes()
    P = [[],[]]
    for i in range(len(V)):
        if f[i] >= 0:        
            P[0].append(V[i])
        else:
            P[1].append(V[i])
    
    return(P)

Let’s see how it is partitioned:

P = partition_with_fiedler(H)
H.show(partition=P, layout='circular', vertex_labels=True, figsize=[10,10])

sage4

Well, not much can be seen yet. Now let me put the red vertices in one side and the blue vertices in the other side:

def position_bottleneck(G):
    P = partition_with_fiedler(G)
    
    V = G.vertices()
    new_pos = {}
    
    for v in V:
        if v in P[0]:
            new_pos[v] = [6*(1+random.random()),6*(2*random.random()-1)]
        else:
            new_pos[v] = [-6*(1+random.random()),6*(2*random.random()-1)]

    return(new_pos)
pos = position_bottleneck(H)
H.show(partition=P, pos=pos, vertex_labels=True, figsize=[10,10])

sage5

Now it’s easy to see the bottleneck of the graph! We can even recover the original picture as follows:

(K,newP) = relable_graph(H,part=P)
K.show(partition=newP, layout='circular', vertex_labels=False, figsize=[10,10])

sage6

And here is the representation of it using the colored edges:

show_random_bottleneck_graph(K,layout='circular') #suggested layouts are "circular" and "spring"

sage7.png


UPDATE:

Since I posted this, I’ve been thinking about multiway Fiedler clustering. Here is what I got so far. First I define a list N of number of vertices in each part, and a matrix A which is basically a probability matrix where entry (i,j) is the probability of an edge between part i and part j, hence it is symmetric. If you choose diagonal entries close to 1 and off-diagonal entries close to zero, then you’ll get a graph with multiple communities. I’ll shuffle the vertices around after creating the multi-community graph.

def multi_bottleneck_graph(N,A):
    #N = list of size n of number of vertices in each part
    #A = an nxn matrix where entry (i,j) shows the probability of edges between part i and part j of vertices, and n is the number of parts.
    
    import random
    
    n = len(N)
    G = Graph({})
    
    
    #add vertices for each part
    for i in range(n):
        for j in range(N[i]):
            G.add_vertex((i,j))
    
    V = G.vertices()
    
    #add edges
    for v in V:
        for w in V:
            if not v == w:
                a = random.random() #generate a random number between 0 and 1
                p = A[v[0],w[0]]
                if a > 1-p: #with probability p add an edge between the two vertices of H1 and H2
                    G.add_edge([v,w])
            
    return(G)

def relable_graph(G,part=None):
    # input: a graph G
    # output: if part is not given, it gives a random labeling of nodes of graph with integers
    #         if part is given, then it partitions the vertices of G labeling each vertex with pairs (i,j) where i in the number of partition the vertex is in part, and j is an integer.
    
    V = G.vertices()
    E = G.edges()
    
    H = Graph({})
    
    map = {}
    if part == None:
        new_part = None
        import random
        random.shuffle(V)
        
        for i in range(len(V)):
            map[V[i]] = i
    else:
        new_part = [ [] for p in part]
        count = 0
        for i in range(len(part)):
            for w in part[i]:
                map[w] = (i,w)
                new_part[i].append((i,w))
                count += 1
    
    for v,w,l in E:
        H.add_edge([map[v],map[w],l])

    return(H,new_part)

def shuffled_multi_bottleneck_graph(N,A):
    G = multi_bottleneck_graph(N,A)
    H = relable_graph(G)[0]
    return(H)

# run
N = [10,15,20]
A = matrix([[.9,.01,.01],[.01,.9,.01],[.01,.01,.9]])
G = shuffled_multi_bottleneck_graph(N,A)
G.show(layout='circular',vertex_labels=False, vertex_size=30, figsize=[10,10])

sage10

Then I break the graph into two pieces using Fiedler vector, compare the two pieces according their algebraic connectivities (second smallest eigenvalue of the Laplacian) and break the smaller one into two pieces and repeat this process, until I get n communities.

def partition_with_fiedler(G):
    # input: a graph G
    # algorithm: using networkx finds the fiedler vector of G
    # a partitioning of vertices into two pieces according to positive and negative entries of the Fiedler vector
    
    import networkx
    H = G.networkx_graph()
    f = networkx.fiedler_vector(H, method='lanczos')
    
    V = H.nodes()
    P = [[],[]]
    for i in range(len(V)):
        if f[i] >= 0:        
            P[0].append(V[i])
        else:
            P[1].append(V[i])
    
    return(P)
    

def multi_fiedler(G,n=2):
    if n == 2:
        P = partition_with_fiedler(G)
        return(P)
    
    else:
        import networkx

        P = partition_with_fiedler(G)
        H = [ G.subgraph(vertices=P[i]) for i in range(2) ]
        C = [ (networkx.algebraic_connectivity(H[i].networkx_graph(), method='lanczos')/H[i].order(),i) for i in range(2) ]
        l = min(C)[1]
        
        while n > 2:
            n = n-1
            
            temP = partition_with_fiedler(H[l])
            nul = P.pop(l)
            P.append(temP[0])
            P.append(temP[1])

            
            temH = [ G.subgraph(vertices=temP[i]) for i in range(2) ]
            nul = H.pop(l)
            H.append(temH[0])
            H.append(temH[1])
        
             
            temC = [ (networkx.algebraic_connectivity(temH[i].networkx_graph(), method='lanczos')/temH[i].order(),i) for i in range(2) ]
            nul = C.pop(l)
            C.append(temC[0])
            C.append(temC[1])
            l = min(C)[1]
            
        return(P)
# run
G.show(partition=K, layout='circular', figsize=[10,10])

sage12

Now I can separate same colour vertices to see the communities in the graph:

def show_communities(G,n):
    #G: a graph
    #n: number of communities > 1
    if n == 1:
        P = [G.vertices()]
    elif n > 1:
        P = multi_fiedler(G,n)
    else:
        raise ValueError('n > 0 is the number of communities.')
    L,newP = relable_graph(G,part=P)
    L.show(partition=newP, layout='circular', vertex_labels=False, figsize=[10,10])

# run
show_communities(G,3)

sage11

There is only one important thing in using networkx. It seems like the default method (tracemin) for algebraic_connectivity and for fiedler_vector has a bug. So, I used the method=’lanczos’ option there.

You might be interested to see what happens if you ask for more or less than 3 communities. Here are a couple of them:

sage22sage24

The next question is how to decide about number of communities.


  1. M. Fiedler, Algebraic connectivity of graphs. Czechoslovak Math. J. 23(98):298–305 (1973).
  2. M. Fiedler, A property of eigenvectors of nonnegative symmetric matrices and its application to graph theory, Czech. Math. J. 25:619–637, (1975).

Two New Movies

I recently went to a couple of screening which made me really happy.

C6aJXKZWgAIgoxQFirst film was “gifted“, the story of a first grader who has a special talent in mathematics and people struggle making a decision between letting her to be an ordinary kid, or coaching her hard to become one of the greatest mathematicians of history. Though the story is somewhat beefed up to become a holywood movie, it shows some of the aspects of the life very nicely. The movie overall was made well, and very much recommended.

Trailer: GIFTED

 

Screenshot at 2017-04-05 12-32-49.pngThe second movie was “codegirl“, more of a documentary about groups of high school girls attacking real life problems in their communities by developing mobile apps. The first scene is a quote from Justin Wolfers, an economist and public policy scholar:

FEWER LARGE COMPANIES
ARE RUN
BY WOMENTHAN BY MEN NAMED JOHN

The movie opens in a small town in Moldova, showing the problems with clean drinking water. The movie goes on to show some of the teams’ early progresses, their struggles, and the emotional moments when a team advances to the next level or gets eliminated. The contrast of types of problems each team has to deal with depending on where they’re from is shown very clearly and beautifully in the movie. The final scenes announcing what some of the teams (eliminated or otherwise) are doing with their projects is particularly inspiring. Highly recommended.

Trailer: CODEGIRL

Nonsymmetric SIEP paper is published in LAA

My first solo paper “Existence of a Not Necessarily Symmetric Matrix with Given Distinct Eigenvalues and Graph” got published in Journal of Linear Algebra and its Applications, yesterday. It took it exactly one year! I’ve written about it here: Losing the Symmetry.

The main idea is to use the implicit function theorem to perturb the following matrix in a way that entries corresponding to the edges become nonzero, and by adjusting the rest of the entries to get back to the original spectrum.

Selection_321Selection_322

You can find the published version here (download for the first 50 days is free).

Academic Cry Baby and the Wall

Yesterday I got several emails from various people at charge at the university stating that they are concerned about the people who are directly affected by the US ban on people from muslim-majority countries to enter US. And what I got from the context was that by “directly affected” they meant business. It is great to live and work in a community that they care about you. One of the emails asked to write up all the ways that we are affected by this law so that they can have a collective report on all the issues and act accordingly when needed.

I told them about a couple of conferences that I am invited to go to in April and in July, and a couple other workshops and conferences that I was planning to participate in, since I was going to be in US any ways. I told them that now I cannot attend these conferences, and can’t give talks there. What I didn’t tell them was that I don’t even know how I am supposed to proceed with this situation. Shall I just email the organizers and tell them that I can’t make it because of these laws, so that they have enough time to replace me? Or shall I still apply for the visa, pay the $160 fee, spend half a work-day for interview, book the hotel and flights, and all the other paperwork, and then hope that in a month or two the problem will be solved? And if it didn’t, then I can email the organizers and hope that they understand my situation? Shall I even consider other conferences in the future? What about the special session at JMM that we were going to organize next year?

I told them about all the jobs that I have applied to in the US and that now even if I get them, I won’t be able to go and work. What I haven’t told them is that I’m now worried that they won’t even consider my application since it will be a 100% waste of their time and resources. What I can’t even get straight in my head is that shall I apply for more jobs in the US, prepare cover letters, read their websites, contact people there, and hope that I get an interview and by the time that I am flying in for the interview miracles happen and they terminate the bans? Or shall I just spend the time and work on my possible less desirable options here, because I know I can stay here if I get the job?

I even told them about my long term concerns that people who are graduating from here or finishing their postdocs won’t be placed in any positions in US, and that means that 10 years from now none of these people will be in any of the US schools. That could affect the university’s ranking, the networks that could be built but won’t exist any more, and the collaborations that are going to be ruined. What I couldn’t tell them is that I moved to US eight years ago knowing that I won’t go back to my country for a long time. So I built connections, I found support groups, friends, and colleagues who stood by me as I went through troubles, and who celebrated with me as I stepped up the stairs of success. People who filled the empty places of my family and friends from back home. These are the people who offered me their home to stay in, their time to spend with me, positions that I could apply for, their basement to hide in if ever FBI is on my foot, research topics to work on together, jobs at their business if I couldn’t find other jobs, and much much more. Even though some of them are jokes, it makes a whole lot of difference to know someone is out there who you can rely on, someone that you can simply spend a night on their couch if you need it, even if that “if” is so far away. It is calming, it’s heart-warming. What I couldn’t talk about is this sense of being supported that I don’t feel that it exists any more, even when many of them call and text me to tell me that they love me, they think of me, and they are sorry for what is happening. The intentions sure exist, but the connections are lost. And no matter what happens to these laws, the stress that it has caused is going to remain. I wish I could tell about these effects to someone!

Of course, compared to the concerns of my friends in US these are just a bunch of nonsense. But they are as real as it can get.

PS1: I need to mention that as an Iranian who lived in US under the Student status, I only had a single-entry visa to US and the risks of getting another one, if I exited the country, was so high that I and many others refrained from exiting US for the entire time that we were students, and even after that. That meant, I never went back home,  missed several conferences that I was invited to attend and give a talk, some very important for my career, and I didn’t even consider participating in many other conferences and workshops. This means, the only difference that the new president has made is that he made the “high chance” to become “certain”. I was called a “potentially terrorist” when I first interviewed for my US student visa (I was 22 back then and I could take things as jokes), and I’ve always been discriminated against because of my country of origin, whether it is at an embassy for a visa interview, that I had to provide lots more documents and wait for undetermined amount of time until they make decisions, or it was applying for a scholarship or a job that they didn’t like Iranians for “security” reasons, or just because they thought I won’t be able to get a visa or permit to work/study there.

PS2: Here is an Statement of Inclusiveness signed by several academics, and it is already adopted by some conferences.

Feedback – part I

Without much ado here is a book that is changing my life:

51n1xhgd9hl-_sx324_bo1204203200_

And why is it changing my life? Well, the book was introduced to me in a workshop about how to make sense of student comments in regular end-of-semester evaluation forms. So, I started reading the book. The premise of the book is that there are various reasons to get triggered when one receives comments and there are different types of feedback and expecting one type and receiving another type causes some troubles. Then it goes into several examples, and many many details of it and ways to prevent some of them, solve some of them, and avoid some others. I particularly like the book because of its scientific approach to writing, but at the same time being very conversational, and my most favourite part is their examples. They provide tons of examples, many case studies, and several extreme examples.

BUT…

It is changing my life because as I keep reading it, I realize that most of communications and relations in one’s life fall into the same categories that the book describes, and one can follow the same strategies to make the whole experience of communicating with others (at any level and of any sort) much much better. To give you an idea of the big picture of the book, let me mention some of the main things:

One of the things that the book mentions is that when you receive a feedback three things can be triggered:

  1. Truth:
    • It is when you feel like the feedback is not representing the truth. For example, “I couldn’t be rude at that party, because I wasn’t at that party. And my name is not Mike!” This is of course one of their extreme examples that makes the whole thing make a lot of sense and I love it. In a more realistic way, I could get a comment from a student that I don’t have a sense of time! While I go to class 5 minutes early and prepare my slides and the notes, and start right at 10 O’clock to lecture. What the student is saying is not the truth. Well, at least not according to my definition. They go and discuss it in much detail that what happens when we feel the comment about us is not the truth and how we can resolve this. Some of the later chapters of the book are on the different aspects of this trigger.
  2. Relationship:
    • It happens when you expect some other type of point of view. For example, a student can tell that “he wasn’t organized.” and you feel like “after all that work that I put into preparing this class and the schedule that I followed to the minute, and extra problems with solutions that I posted online, you tell me this?”. Or in a different way, you might get a comment that “He knows math but he doesn’t know how to teach it!” And you’ll be like “Who the hell are you to judge my teaching?!” There are a lot to be learnt from the feedback when this gets triggered and the book spends a good amount on this topic.
  3. Identity:
    • It is when you feel like you don’t know who you are, e.g. “Maybe I am a bad teacher after all”, or “What am I doing with my life teaching these courses?” And there are many other things that can be done in this case too.

The book goes on to identify three types of feedback:

  1. Praise:
    • “Good job”, “Awesome teacher”, “Worst instructor ever” etc are examples of praise. It doesn’t have much information in it. It simply says the feedback giver is happy or not with the performance. We all need that at times and some times we receive that feedback.
  2. Coaching:
    • “Give us more time during the class to work on problems”, “provide more examples”, “he talks too fast (i.e. don’t talk too fast)” etc are examples of coaching. They have lots of information in them and usually these what make you grow.
      • If I’m looking for praise and receive coaching instead, I’ll be maaaaaaaaaaaaad! “I’m spending lots of time preparing for this course, don’t tell me I need to use a larger size font on the worksheets!”.
      • If I’m looking for coaching and receive praise instead, I’ll be alright but frustrated as I don’t know where to go next. “OK, the exam I designed was a good exam and covered all the material, but how can I make it more related to practice problems students are doing? how do I make sure that it’s not too much for 2 hours? How would I ask a reasonable question about that topic that I didn’t ask about it?”.
  3. Evaluation:
    • Your salary gets raised, a student sings up for your next class after they had a course with you before, you get fired, your spouse wants a divorce, you get accepted to graduate school. These are examples of evaluation.
      • If I’m looking for praise and I receive evaluation instead, I’ll feel a little lost. “OK, my contract got extended, but am I doing well enough? Are you happy with me?”.
      • If I’m looking for evaluation and I get praised instead, I’ll feel they’re hiding something. “Yeah, I know I’m doing a good job, will you sign my contract for next year or not, though?”.
      • If I’m looking for coaching and receive evaluation instead, it’s just unsettling. “My application for this job got rejected, but you haven’t told me what are the strong and weak points on my portfolio, how do I improve it so that I get the job next year, what are the things that you were looking for ans was lacking in my application?”.
      • If I’m looking for evaluation and I get coaching instead, I won’t care! “Are you gonna hire me or not? I don’t care that I should have gone to that conference!”

Then the book goes into every detail of every aspect of these topics and provides many many beautiful examples, and comes up with strategies to figure out what situation we are in and how to respond to each situation when facing them. I don’t necessarily agree with all of their strategies, and I think on several cases I can do the exact opposite of what they suggest and have a better outcome, but the book is extremely helpful in identifying these situations and classifying them.

If you gave it a try, let me know what you think about it, the whole book, or any of the single details. I’d love to discuss the topics to learn more.

Pidgin and batch rename in python

I remembered that I can use pidgin! I don’t know what I haven’t been using it for a while. But now that I’ve installed it again, I went and downloaded yahoo smilies (from here) and the according to this page I had to copy the unzipped file to ~/.purple/smileys folder. Everything worked fine, expect since the file I downloaded had a bunch of files that were all named like yahoo\26.gif and that made pidgin not to recognize them! So I had to change them, but it seems like also shell doesn’t like \ in file names either. So I asked python to help me. Here is the code:

import os
directory = '/home/k1/.purple/smileys/yahoo/'
for filename in os.listdir(directory):
    if filename.startswith('yahoo'):
            print('renaming', filename)               
            os.rename(directory+filename, directory+filename[6:])

This deletes yahoo\ part of each file that has it. In the if part I couldn’t write if filename.startswith('yahoo\'): and if I wanted to be precise I had to write if filename.startswith('yahoo\\'):. Anyways, going to pidgin, tools, preferences, themes, I chose the yahoo smilies from the dropdown list.
The following is the info from the mentioned page above:

Smiley Themes

Installing

One important thing to remember is that these smileys only show up on your side. Unless the person you’re talking to has the same theme as you installed in the same client, it’s not guaranteed that they will see the same pictures as you for the smileys.

The way smiley themes work is quite simple. We’ll use an example to explain how it works. The name of this theme will be “Hello World!”.

If we wanted to install Hello World! into pidgin, we would have to do one of three things:

  • Copy a folder, whose contents are described below, into ~/.purple/smileys (See the FAQ for the location of ~/.purple on Windows)
  • Drag a tar.gz file (it must be a gzipped tarball), whose contents are described below, onto the list of smiley themes in Tools -> Preferences
  • Click the “Add” button in the “Smiley Themes” tab in the preferences, navigate to your <theme>.tar.gz file, and click “Open”.

Creating

The first thing you need to know is the contents of the tarball you drag into the smiley themes list. It contains the folder that is described in option 1 above. In our case, this folder would probably be called “Hello_World”.

Now to describe the contents of Hello_World. This folder contains all the information Pidgin needs to use your theme. It has a lot of picture files that will be how your smileys show up (to you) and a text file named “theme”, which tells pidgin what to do with all those pictures. For this example, lets let our list of picture files be:

  • happy.png
  • sad.png
  • grin.png
  • hidden.png
  • MSN_only.gif
  • GoogleTalk.gif

Then let our theme file look like so:

Name=Hello World!
Description=Smiley Theme How-To
Icon=happy.png
Author=Ankit Singla

[default]
! hidden.png			C:-) C:)
sad.png				😦 😦
happy.png			🙂 🙂
grin.png		😀 :-d

#These show up only in MSN
[MSN]
sad.png				😦 😦
happy.png			🙂 🙂
grin.png		😀 :-d
MSN_only.gif	:-M :-$

#These show up only in XMPP
[XMPP]
sad.png				😦 😦
happy.png			🙂 🙂
grin.png		😀 :-d
GoogleTalk		:-G :T

Blank lines and lines that start with # are ignored. The # means this line is a comment. Lines starting with a ! means to hide that particular emoticon from the emoticon selector dialog.

The first four lines are part of any theme. The first line is the name of our theme, in our case “Hello World!”. This shows up in the theme selector in bold. The second line is the description of our theme. This shows up underneath the name and author in the theme selector. The third line is the icon to show in the theme selector, which is a quick way for the user to see which theme they’re selecting. The last line is the author of the theme. This shows up next to the name of the theme in the theme selector.

Next come the protocol specific sets of smileys. A set of smileys is defined in the following format:

[<protocol>]
<picture to use>	<text to replace>
.
.
.

For example:

[MSN]
sad.png				😦 😦
happy.png			🙂 🙂
grin.png		😀 :-d
MSN_only.gif	:-M :-$

This means, the first line defines which protocol this set defines. In our example, this set will define all of the MSN pictures. Each line after that specifies how to handle each picture you want to use in that protocol. The first element on this line is the name of the picture, so for our first picture, we have sad.png. This must be followed by some whitespace and then a list of strings, separated by whitespace, that will be replaced by the picture sad.png in conversation. So in our case, we’re telling pidgin that if it ever sees “:(” or “:-(“, it shouln’t show us “:(” or “:-(“. Instead, it should replace it with sad.png so we see that picture instead.

The first set defined in a theme file is usually the default set. This is the set of smileys that pidgin uses if it doesn’t find a protocol specific set for that protocol in the rest of the file. So in our file, it will use the default set for AIM, ICQ, IRC, etc. If you notice, in the default set there’s a line that starts with an exclamation point. This means the smiley is hidden. If someone types the text associated with that picture, you’ll see the picture, but you won’t be able to pick that smiley from the smiley selector that pops up from the formatting toolbar.

That’s it! Congratulations, you know how to make a theme file.