Python: Sorting a dictionary on (key, value) order

We might come into a scenario when we need to use not only one but two, three or more attributes to sort a list or dictionary in Python (similar to order by field1, field2, field3… analogy in SQL).

Take the below dictionary for example:

{'a': 2, 'b': 3, 'c': 2, 'd': 1, 'e': 1}

The sorted output desired is below:

d 1
e 1
a 2
c 2
b 3

Note that the first sort order is on the [value] ascending and second sort order is on ascending alphabetical order of the [key]. This can be achieved as shown in the following snippet:

alphabet_count = {'a': 2, 'b': 3, 'c': 2, 'd': 1, 'e': 1}
for key in sorted(alphabet_count.keys(), key=lambda x:(alphabet_count[x], x), reverse=False):
     print(key, alphabet_count[key])

Now what if the desired output is descending [value] and ascending [key] as below:

b 3
a 2
c 2
d 1
e 1

We can tweak the sign on the [value] field to reach at a solution. Eg.

alphabet_count = {'a': 2, 'b': 3, 'c': 2, 'd': 1, 'e': 1}
for key in sorted(alphabet_count.keys(), key=lambda x:(-alphabet_count[x], x), reverse=False):
     print(key, alphabet_count[key])

In short, it is key to remember to group the sorting attributes in order in a tuple i.e. (x, y, ..) format in the lambda function.

Coaxing apache to honour OPTIONS

Browsers like FF 3.5 sends a ‘preflight’ OPTIONS request first before sending the actual request in GET/POST. Adding the following directives in httpd.conf will send a 200 response code to client browser without actually executing any handler script and then browser seems to send the POST/GET request – to actually execute script with proper parameters.

# enable cross domain access control 
Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS" 
 
# force apache to return 200 
RewriteEngine On 
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule .* / [R=200,L] 

Linux trivia : vi settings

Ever faced the problem of cursor getting reset to beginning of file each time you open it in vi! Well, adding the following to .vimrc in your home directory or /etc/vimrc (whichever is appropriate) will get the cursor back to where you left it in last session.

if has(“autocmd”)
” In text files, always limit the width of text to 78 characters
autocmd BufRead *.txt set tw=78
” When editing a file, always jump to the last cursor position
autocmd BufReadPost *
\ if line(“‘\””) > 0 && line (“‘\””) <= line(“$”) |
\   exe “normal g’\”” |
\ endif
endif

Linux trivia : awk trick

[dparasar@/home/dparasar]$ cat test.txt
catchmeifucanblahblahblahcatchmeifucanblahblah———-  blahcatchmeifucan
catchmeifyoucan~~~~~~~~~~~~~~~yruyoiupoipipi[catchmeifyoucan897980

fdsfdhgfjgkkh
D
D
asdsdgfdfdhcatchmeifucanxxxxxxxxxxcatmek

[dparasar@/home/dparasar]$awk  ‘BEGIN{FS=”catchmeifucan”;};/catchmeifucan/ {count += NF-1; print “No of total matches after ” NR” line: ” count} END {print “Total matches ” count;}’

No of total matches after 1 line: 3
No of total matches after 7 line: 4
Total matches = 4

PHP installation and setup.

Listed below are steps to install and configure PHP on windows. ( I was initially having problem with the same ).

1. Download PHP 5 from http://www.php.net/downloads.php. ( It is better to chose any zipped windows binary rather

than the  installer itself, as manual configuration is the best way in any case.)

2. Create a folder c:/php and extract files to the same. Take up php.ini-recommended and rename it to php.ini

and save it in the same folder.

3. Add  c:/php  to the  PATH  variable.  (  Control Panel->System->Advanced->Environment Variables->Edit Path

and restart the system.)

4. Time to edit php.ini. Open this in some ASCII editor ( eg. Notepad) and edit as below.

short_open_tag = On # tags like “<?” will be recognised as the start tag for a PHP script.

magic_quotes_gpc = On # If you want your input data to have the backslash (“\”) prefix.

The above should suffice for time being.

5. Configure Apache to load php modules/library.

Add the following to httpd.conf

LoadModule php5_module “c:/php/php5apache.dll” # If Apache 1.x series

LoadModule php5_module “c:/php/php5apache2.dll” # If Apache 2.0.x series

LoadModule php5_module “c:/php/php5apache2_2.dll” # If Apache 2.2.x series

AddModule mod_php5.c # Only if Apache 1.x

AddType application/x-httpd-php .php # Add under <IfModule mime_module> just before </IfModule>

AddType application/x-httpd-php .phtml # If .phtml support is required.

PHPIniDir “c:/php” # Add at the end of httpd.conf to indicate the location of php.ini.

6.  Create a simple php file index.php with the below content for test purpose

<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo “Hello World! This is PHP calling\n”; phpinfo();?>
</body>
</html>

To see this as apache indexpage  edit DirectoryIndex  in apache httpd.conf  as  below:

DirectoryIndex index.php index.html #  Fails  over to index.html  if index.php is not there.

7. Restart Apache. In http://localhost contents of index.php should be displayed. (Not the code content of course!)

Create DML from tables eg. insert statements from all rows in a table

The following was tested on Oracle 11g.

1. Create a function as below

create or replace FUNCTION GET_INSERT_SCRIPT (V_TABLE_NAME VARCHAR2)
RETURN VARCHAR2 AS
B_FOUND BOOLEAN := FALSE;
V_TEMPA VARCHAR2 (8000);
V_TEMPB VARCHAR2 (8000);
V_TEMPC VARCHAR2 (255);
BEGIN
FOR TAB_REC IN (SELECT TABLE_NAME
FROM ALL_TABLES
WHERE TABLE_NAME = UPPER (V_TABLE_NAME)) LOOP
B_FOUND := TRUE;
V_TEMPA := ‘select ”insert into ‘ || TAB_REC.TABLE_NAME || ‘ (‘;

FOR COL_REC IN (SELECT *
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME = TAB_REC.TABLE_NAME
ORDER BY COLUMN_ID) LOOP
IF COL_REC.COLUMN_ID = 1 THEN
V_TEMPA := V_TEMPA || ”’||chr(10)||”’;
ELSE
V_TEMPA := V_TEMPA || ‘,”||chr(10)||”’;
V_TEMPB := V_TEMPB || ‘,”||chr(10)||”’;
END IF;

V_TEMPA := V_TEMPA || COL_REC.COLUMN_NAME;

IF INSTR (COL_REC.DATA_TYPE, ‘CHAR’) > 0 THEN
V_TEMPC := ””””’||’ || COL_REC.COLUMN_NAME || ‘||””””’;
ELSIF INSTR (COL_REC.DATA_TYPE, ‘DATE’) > 0 THEN
V_TEMPC :=
”’to_date(”””||to_char(‘
|| COL_REC.COLUMN_NAME
|| ‘,”mm/dd/yyyy hh24:mi”)||”””,””mm/dd/yyyy hh24:mi””)”’;
ELSE
V_TEMPC := COL_REC.COLUMN_NAME;
END IF;

V_TEMPB :=
V_TEMPB
|| ”’||decode(‘
|| COL_REC.COLUMN_NAME
|| ‘,Null,”Null”,’
|| V_TEMPC
|| ‘)||”’;
END LOOP;

V_TEMPA :=
V_TEMPA
|| ‘) values (‘
|| V_TEMPB
|| ‘);” from ‘
|| TAB_REC.TABLE_NAME
|| ‘;’;
END LOOP;

IF NOT B_FOUND THEN
V_TEMPA := ‘– Table ‘ || V_TABLE_NAME || ‘ not found’;
ELSE
V_TEMPA := V_TEMPA || CHR (10) || ‘select ”– commit;” from dual;’;
END IF;

RETURN V_TEMPA;
END;

2. Call the function like

select get_insert_script(<tablename>) from dual

eg. select get_insert_script(‘hosts’).

I get a consolidated sql script like below :

select ‘insert into HOSTS (‘||chr(10)||’HOSTNAME,’||chr(10)||’SUPPORT_GROUP,’||chr(10)||’ESCALATION_GROUP) values (‘||decode(HOSTNAME,Null,’Null’,””||HOSTNAME||””)||’,’||chr(10)||”||decode(SUPPORT_GROUP,Null,’Null’,””||SUPPORT_GROUP||””)||’,’||chr(10)||”||decode(ESCALATION_GROUP,Null,’Null’,””||ESCALATION_GROUP||””)||’);’ from HOSTS;

Running the above script in sql prompt I get the insert statements for all the rows in ‘hosts’ table.

PL/SQL : Duplicate elimination from a table.

Supposing a table having a hostname column are peppered with duplicate values in the same field.

To eliminate duplicate and keep only one of a kind….

declare

cursor c1 is

select distinct hostname from <table>;

begin

for record in c1

loop

delete from <table> where hostname = record.hostname

and

rownum != (select count(*) from <table> where hostname = record.hostname);

end loop;

end;