Tech Chorus

How To Interchange Values And Keys Of A Dictionary In Python?

written by Sudheer Satyanarayana on 2015-12-09

Here's our sample dictionary:

my_dict = {'game': 'cricket', 'planet': 'earth'} The values() method of the dictionary returns a list of values.

>>> my_dict.values()
['earth', 'cricket']

The keys() method of the dictionary returns a list of keys.

>>> my_dict.keys()
['planet', 'game']

Notice the 1-1 correspondence between the items of the returned lists. This correspondence remains unchanged if the dictionary is unchanged.

To interchange the keys and values all you have to do is zip and generate another dictionary. Let's complete the remaining steps.

zip(my_dict.values(), my_dict.keys())
[('earth', 'planet'), ('cricket', 'game')]

Now, we have a list of tuples. Each tuple contains the value and key pairs. The last step is to create a dictionary using this list. Pass the above list to the built-in function dict().

>>> dict(zip(my_dict.values(), my_dict.keys()))
{'earth': 'planet', 'cricket': 'game'}

Here's a one-liner to summarize the concept.

dict(zip(my_dict.values(), my_dict.keys()))

Github For Mercurial User

written by Sudheer Satyanarayana on 2015-03-27

You are a Mercurial user and have little experience with Github. You are required to publish your Mercurial repository on Github. The good news is, you can do it without parting with Mercurial. There are bridges between Git and Mercurial. The one we are going to talk about today, is hg-git.

Let's start demonstrating our solution.

Step 1: Create a mercurial repository somewhere

I do it on Bitbucket. We'll call this our canonical repository. Clone the repository.

hg clone ssh://hg@bitbucket.org/bngsudheer/mycoolrepo

Step 2:Add some contents to the cloned repository

cd mycoolrepo/
echo "Sudheer Satyanarayana" >> contributors.txt
hg add contributors.txt
hg commit -m "Initial commit with contributors"

Step 3: Push the changes to the canonical Mercurial repository

hg push ssh://hg@bitbucket.org/bngsudheer/mycoolrepo

Step 4: Create the repository on Github

There are several ways to setup the mirror. One way to do it is importing the Mercurial repository to Gitbut. But in this article, we'll directly pull and push to Github repository. While creating the Git repository on Github, I chose the option - "Initialize this repository with a README".

Step 5: Enable the hg-git extension

Edit .hg/hgrc file in your repository and add these:

[extensions]
hggit =

Step 6: Pull from the newly created Git repository

hg pull git+ssh://git@github.com:bngsudheer/mycoolrepo.git

Pulling for the first time from the newly created Git repository will create another head in your Mercurial repository. For example, running 'hg heads' shows:

changeset:   1:5b467a77b006
bookmark:    master
tag:         tip
parent:      -1:000000000000
user:        Sudheer Satyanarayana <sudheer.zzz@sudheer.net>
date:        Fri Mar 27 22:14:32 2015 +0530
summary:     Initial commit

changeset:   0:688bd09fe790
user:        sudheer
date:        Fri Mar 27 22:07:26 2015 +0530
summary:     Initial commit with contributors
The changeset 1:5b467a77b006 is bookmarked as 'master'.

Step 7: Merge the heads

hg merge master
hg commit -m "merging master"

Step 8: Push the changeset to the canonical Mercurial repository

hg push

Move the bookmark 'master' to default and push to Githib.

hg bookmark -r default master
hg push git+ssh://git@github.com:bngsudheer/mycoolrepo.git

Now, you can adopt this method to work on the repository and keep pushing to both the repositories - The canonical Mercurial repository and the Github Git repository.

Work on the repository. Make some commits. Push to the canonical repository Move the bookmark 'master' to default and push to Githib Git repository If you do not move the bookmark, pushing to the Git repository makes no sense because hg-git will attempt to push the changeset the bookmark points to. In other words, the bookmark 'master' needs to be updated every time you want to push to the Git repository. You can automate the process of moving the bookmark to your latest line of work by activating the bookmark.

hg up master

That's it. Now your working method is:

Work on the repository. Make some commits. Push to the canonical repository Push to Githib Git repository Once the bookmark is active, Mercurial moves the bookmark to your latest line of work automatically.

Short repository name: For your convenience, you can give a short name to your Github repository URL. In your .hg/hgrc update the paths secion:

[paths]
default = ssh://hg@bitbucket.org/bngsudheer/mycoolrepo
github = git+ssh://git@github.com:bngsudheer/mycoolrepo.git

Notes: Make sure not to add '.git' directory. Github will not accept the changeset if there is a '.git' directory.

Access Dictionary Keys As Object Attributes

written by Sudheer Satyanarayana on 2015-02-24

You access Python dictionary keys using the syntax:

my_dicy[my_key]

For example:

>>> my_dict = {'food': 'idly'}
>>> my_dict['food']
'idly'

Sometimes, you might want to access the dictionary keys using:

my_dict.my_key

syntax. If you do this is what happens:

>>> my_dict.food
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'food'

How can you solve this? Easy.

 pip install attrdict

How do you use the newly installed package?

>>> from attrdict import AttrDict
>>> my_dict = AttrDict({'food': 'idly'})
>>> my_dict.food
'idly'

How to get Fedora to suspend laptop when lid is closed?

written by Sudheer Satyanarayana on 2015-02-24

Edit the file:

/etc/systemd/logind.conf

Look for the 'HandleLidSwitch' entry. Add the entry if it is not there already. If the entry is already there, change to:

HandleLidSwitch=hibernate

Then restart systemd-logind:

systemctl restart systemd-logind.service

This is tested on Fedora 21.

Pani

written by Sudheer Satyanarayana on 2014-10-21

Pani version 0.1 has been released.

Pani is a glue tool that provides a web interface atop hg-ssh. Through the web interface, you can add, modify and remove packages and assign access to users.

The documentation is also available.

How To Change Hostname In CentOS 7

written by Sudheer Satyanarayana on 2014-10-07

CentOS 7 comes with the hostnamectl utility to read and write hostname.

To view the hostname simply run the command:

hostname

[root@c7p1 ~]# hostnamectl
Static hostname: localhost.localdomain
Icon name: computer
Chassis: n/a
Machine ID: cda43e8062fb4d5881491f41e06a0c0d
Boot ID: 7cb835d3dd64468392e3399d771051ac
Virtualization: kvm
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-123.el7.x86_64
Architecture: x86_64

To set a hostname:

hostnamectl set-hostname mynewhostname

Example:

hostnamectl set-hostname c7p1.v.lab.techchorus.net

How To Setup MySQL Replication

written by Sudheer Satyanarayana on 2013-11-05

In this tutorial, I will provide step by step process to setup MySQL replication. We will create one master and one slave. We will use two CentOS 6 servers - one for master and the other for slave. This following steps have been tested on two virtual machines.

Our master server will have IP address 192.168.122.10. Our slave server will have IP address 192.168.122.12.

You might want to run SELinux in permissive mode.

Perform these steps on the master:

Install MySQL server.

yum install mysql-server -y

Configure binary log and assign server ID to master. In /etc/my.cnf append the following to mysqld section:

log-bin=mysql-bin
server-id=1

Each server will have a unique ID. Our master will have ID 1 and slave 2.

Start the MySQL server.

/etc/init.d/mysqld start

Set up the initial MySQL server settings.

mysql_secure_installation

Create a MySQL user account and provide REPLICATION SLAVE access to it.

mysql> CREATE USER 'repl'@'192.168.122.12' IDENTIFIED BY 'secretpassword';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.122.12';

Be sure to replace 'secretpassword' with the actual password. Also, note that 192.168.122.12 is the IP address of the slave server. repl MySQL user will be able to access the master server only from the IP address 192.168.122.12.

Let us create a sample database, table and a row.

mysql>CREATE DATABASE sample;
mysql>USE sample;
mysql>CREATE TABLE mytable (mycol varchar(255));
mysql>INSERT INTO mytable VALUES ('first entry');

At this point, we will prepare the master server for replication.

First, we lock all the tables.

mysql>FLUSH TABLES WITH READ LOCK;

Then, we note down the binary log file and position.

mysql>  SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |     1377 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

The log file is mysql-bin.000003 and position is 1377. The values on your server may vary.

Don't exit the MySQL client. In a separate session/terminal run the following commands.

Stop MySQL server.

/etc/init.d/mysqld stop

Copy the files to the slave server.

rsync --recursive /var/lib/mysql root@192.168.122.12:/var/lib --exclude="mysql/mysql" --exclude='mysql-bin.*' --exclude='auto.cnf' -v

If you use other methods to copy the data, be sure to exclude mysql.bin, auto.cnf and mysql directory placed inside /var/lib/mysql.

auto.cnf was added in MySQL 5.6.

Start the MySQL server.

/etc/init.d/mysqld start

Perform these steps on the slave server.

Install MySQL server.

yum install mysql-server -y

Make sure mysql is the owner of the files.

chown -R mysql.mysql /var/lib/mysql/

Edit /etc/my.cnf and append the following line in mysqld section.

server-id=2

Start the MySQL server.

/etc/init.d/mysqld start

Perform the initial settings.

mysql_secure_installation

Inform the slave how to access the master server.

mysql> CHANGE MASTER TO
        MASTER_HOST='192.168.122.10',
        MASTER_USER='repl',
         MASTER_PASSWORD='secretpassword',
         MASTER_LOG_FILE='mysql-bin.000003',
         MASTER_LOG_POS=1377;

Remember 1377 is the position and mysql-bin.000003 is the log file name after we locked the tables on master and copied the files.

Start the slave.

mysql> START SLAVE;

You can check the slave status using:

mysql> SHOW SLAVE STATUS\G;

Here's a sample output:

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.122.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 214
               Relay_Log_File: mysqld-relay-bin.000003
                Relay_Log_Pos: 359
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 214
              Relay_Log_Space: 660
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
1 row in set (0.00 sec)

ERROR: 
No query specified

The key fields are Slave_IO_State, Slave_IO_Running and Slave_SQL_Running.

Let's see if our sample database has been copied.

mysql> USE sample;
mysql> SELECT * FROM mytable;

On the master run a few SQL statements.

mysql> USE sample;
mysq;> INSERT INTO mytable VALUES ('second entry');

On the slave, verify whether replication is working.

mysql> USE sample;
mysql> SELECT * FROM mytable;

Reference: MySQL reference manual

How To Setup php-fpm And Nginx On CentOS 6

written by Sudheer Satyanarayana on 2013-05-19

FPM, FastCGI Process Manager is a PHP FastCGI implementation. Using php-fpm you can have a website running as its own user instead of a common user like Apache or www-data. In this post, we will go through the process of installing and configuring php-fpm with Nginx on CentOS 6.

php-fpm package is available in the official CentOS repository. There is no need to enable third party repositories in order to use php-fpm.

nginx package is available in Fedora EPEL repository.

Enable Fedora EPEL.

rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

Install nginx and php-fpm packages.

yum install nginx php-fpm

Create a user for our website.

useradd webuser1

As user webuser1, create the directory where we will have our PHP scripts.

mkdir  /home/webuser1/www/public -p

Also create the log directory.

mkdir /home/webuser1/logs

Let web server execute files in our home directory.

chmod o+x /home/webuser1/

Create the file /home/webuser1/www/public/index.php and write some sample PHP code in it.

<?php
phpinfo();
?>

Configure php-fpm. Craete the file /etc/php-fpm.d/webuser1.conf and add the below contents.

[webuser1]
listen = 127.0.0.1:9001
listen.allowed_clients = 127.0.0.1
user = webuser1
group = webuser1

pm = dynamic
pm.max_children = 15
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 5
pm.max_requests = 2000

request_slowlog_timeout = 5
slowlog = /home/webuser1/logs/webuser1.slow.log

php_admin_value[error_log] = /home/webuser1/logs/webuser1.error.log
php_admin_flag[log_errors] = on

The FastCGI server runs on port 9001 and the IP address 127.0.0.1. The process user and group should be webuser1. We also specify where to send the logs. Start php-fpm daemon.

/etc/init.d/php-fpm start

Configure Nginx. Within /etc/nginx/nginx.conf in the http block, add:

server_names_hash_bucket_size 64; Create the file, /etc/nginx/conf.d/webuser1.conf and append the following contents.

server {
    listen       80;
    server_name yourwebsite.example.com;

    root   /home/webuser1/www/public;
    index  index.html index.htm index.php;

    location ~ \.php$ {
      fastcgi_pass   127.0.0.1:9001;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      include        fastcgi_params;
    }
}

Start Nginx.

/etc/init.d/nginx start

That is all you have to do to setup php-fpm and Nginx on CentOS 6.

How To Comment Several Lines Quickly Using VIM

written by Sudheer Satyanarayana on 2012-12-20

If you have to insert comment on several lines do you do manually insert the comment character in every line? Stop. Vim is a really good editor and has a nice feature to accomplish this quickly. Here are the steps:

  1. Enter visual blocking mode by pressing CTRL V (CTRL key and the lowercase v). 1 .Make your selection using motion keys(jklm, etc).
  2. Press I(uppercase I) to enter block insert mode.
  3. Press #, the comment character.
  4. Press Esc key. The comment character # will be inserted on each line the visual block selection.

Read more about visual blocking mode using the vim help topic visual-block. At the command line(:), type help visual-block.

How Many Seconds Are There Till End Of Month?

written by Sudheer Satyanarayana on 2012-09-17

(datetime.datetime(datetime.datetime.today().year, datetime.datetime.today().month, calendar.monthrange(datetime.datetime.today().year, datetime.datetime.today().month)[1]) - datetime.datetime.today()).total_seconds()

There's a lot going on in that one liner. Let's break it down.

The two key Python modules we need to calculate the number of seconds till the end of year are datetime and calendar.

calendar.monthrange(year, month) returns a tuple. The tuple's second element is the number of days in the month.

We create two date objects:

We subtract object 1 from object 2. Finally, we call .total_seconds() on the resultant object.

>>> import datetime
>>> import calendar
>>> (datetime.datetime(datetime.datetime.today().year, datetime.datetime.today().month, calendar.monthrange(datetime.datetime.today().year, datetime.datetime.today().month)[1]) - datetime.datetime.today()).total_seconds()
1290914.259939
>>>