Python 101: Learning by doing. 
Looping through a dictionary (aka map):

Python 2.7.5
>>> map = {50+i:i for i in range(10)}
>>> map
{50: 0, 51: 1, 52: 2, 53: 3, 54: 4, 55: 5, 56: 6, 57: 7, 58: 8, 59: 9}
>>> for key, value in map.iteritems():
... print key,'-',value
...
50 - 0
51 - 1
52 - 2
53 - 3
54 - 4
55 - 5
56 - 6
57 - 7
58 - 8
59 - 9
>>>

Python 3.3.2
>>> map = {50+i:i for i in range(10)}
>>> map
{50: 0, 51: 1, 52: 2, 53: 3, 54: 4, 55: 5, 56: 6, 57: 7, 58: 8, 59: 9}
>>> for key, value in map.items():
... print(key,' - ',value)
...
50 - 0
51 - 1
52 - 2
53 - 3
54 - 4
55 - 5
56 - 6
57 - 7
58 - 8
59 - 9
>>>


Fetching url data:

Python 2
[aesteban@localhost corpemployees-filtered]$ python
Python 2.7.5 (default, Apr 10 2015, 08:09:05)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import urllib
>>> urllib.urlopen('https://graph.facebook.com/?id=http://www.barney.com').read()
'{"id":"http:\\/\\/www.barney.com","shares":792}'

Python 3
[aesteban@localhost corpemployees-filtered]$ python3
Python 3.3.2 (default, Dec 4 2014, 12:49:00)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import urllib.request
>>>
>>> urllib.request.urlopen('https://graph.facebook.com/?id=http://www.barney.com').read()
b'{"id":"http:\\/\\/www.barney.com","shares":792}'


[ view entry ] ( 1474 views )   |  print article
MySQL: Loading a TSV file into a table. 
1.- The column names are in the first line, get them:
[aesteban@localhost BizEquityData]$ head -1 bizDataFile.tsv | tr '\t' '\n'
id
name
dbaname
address
city
state
postcode
latitude
longitude
phone
faxphone
contact
firstname
lastname
email
yearestablished
businessstatus
webaddress
corpemployees
localemployees
corpamount
localamount
localamount
stockexchangecode
stocktickersymbol
ceoname
cioname
cfoname
name
code

1a..- find out total lines in file:
[aesteban@localhost BizEquityData]$ cat bizDataFile.tsv | wc -l
1785338

2.- Create a table, rename any duplicate field names:
CREATE TABLE `bizDataTable` (
id varchar(255),
name varchar(255),
dbaname varchar(255),
address varchar(255),
city varchar(255),
state varchar(255),
postcode varchar(255),
latitude varchar(255),
longitude varchar(255),
phone varchar(255),
faxphone varchar(255),
contact varchar(255),
firstname varchar(255),
lastname varchar(255),
email varchar(255),
yearestablished varchar(255),
businessstatus varchar(255),
webaddress varchar(255),
corpemployees varchar(255),
localemployees varchar(255),
corpamount varchar(255),
localamount varchar(255),
localamount2 varchar(255),
stockexchangecode varchar(255),
stocktickersymbol varchar(255),
ceoname varchar(255),
cioname varchar(255),
cfoname varchar(255),
name2 varchar(255),
code varchar(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.- Connect to the server and load the local file:
[aesteban@localhost BizEquityData]$ mysql -u USERNAME -h dev.example.com -p --local-infile bizDataDB
MySQL [bizDataDB]> load data local infile '/home/aesteban/Documents/BizEquityData/bizDataFile.tsv' into table bizDataTable fields terminated by '\t' lines terminated by '\n' ignore 1 lines;

MySQL [bizData]> select count(*) from bizDataTable;
+----------+
| count(*) |
+----------+
| 1785337 |
+----------+
1 row in set (0.00 sec)


Enjoy!!

BONUS: Dump select statement locally as a TSV file:
[aesteban@localhost FilteredReports]$ mysql -u USERNAME -h dev.example.com -p bizDataDB -e "select * from bizDataTable where email != 'NULL'" > bizData_email.tsv


If it's a CSV file, some fields may contain a comma, try something like the following:
MySQL [jupiter]> load data local infile 'e360Data.csv' into table e360MasterOnline fields optionally enclosed by '"' terminated by ',' lines terminated by '\n' ignore 1 lines;



[ view entry ] ( 1510 views )   |  print article
BASH 101: Dollar sign madness 
positional parameters, parameters passed to script.
$1, $2, $3, ... 

It's an array-like construct of all positional parameters, {$1, $2, $3 ...}.
"$@" 

It's the IFS expansion of all positional parameters, $1 $2 $3 ....
"$*" 

It's the number of positional parameters.
$# 

current options set for the shell.
$- 

pid of the current shell (not subshell).
$$ 

most recent parameter (or the abs path of the command to start the current shell immediately after startup).
$_ 

It's the (input) field separator.
$IFS 

It's the most recent foreground pipeline exit status.
$? 

It's the PID of the most recent background command.
$!

It's the name of the shell or shell script.
$0


http://stackoverflow.com/questions/5163 ... -variables

[ view entry ] ( 1295 views )   |  print article
BASH 101: Functions 
EXAMPLE A) Declaring a function in sum.sh script:
#!/usr/bin/bash

sum()
{
echo $1 + $2 | bc
}

# call function and pass cli
# parameters to function
sum $1 $2

Calling script:
[aesteban@localhost ~]$ ./sum.sh 1.4 1.3
2.7

EXAMPLE B) A different way to write sum.sh script:
#!/usr/bin/bash

sum()
{
RESULT=$(echo $1+$2 | bc) # or: RESULT=`echo $1+$2 | bc`
}

sum $1 $2

echo $RESULT

Calling modified script:
[aesteban@localhost ~]$ ./sum.sh 1.7 1.2
2.9

EXAMPLE C) Another way to write the same crap:
#!/usr/bin/bash

sum()
{
echo $1+$2 | bc
}

SUMRESULT=`sum $1 $2`

echo $SUMRESULT

Calling it:
[aesteban@localhost ~]$ ./sum.sh 2.9 3
5.9


[ view entry ] ( 1340 views )   |  print article
BASH 101: Notes 
#local variables
[aesteban@localhost ~]$ Name=Angel
[aesteban@localhost ~]$ echo $Name
Angel
[aesteban@localhost ~]$ Name="Angel Cool"
[aesteban@localhost ~]$ echo $Name
Angel Cool
[aesteban@localhost ~]$ #readonly
[aesteban@localhost ~]$ readonly Name
[aesteban@localhost ~]$ Name="Angel Esteban"
bash: Name: readonly variable
[aesteban@localhost ~]$

#index arrays
[aesteban@localhost ~]$ Fruits[0]=apple
[aesteban@localhost ~]$ Fruits[1]=orange
[aesteban@localhost ~]$ Fruits[2]=banana
[aesteban@localhost ~]$ Fruits[3]=grapes
[aesteban@localhost ~]$
[aesteban@localhost ~]$ States=("California" "Texas" "Florida")
[aesteban@localhost ~]$ echo ${States[1]}
Texas

[aesteban@localhost ~]$ echo ${Fruits[2]}
banana
[aesteban@localhost ~]$ echo ${Fruits[*]}
apple orange banana grapes
[aesteban@localhost ~]$ echo ${#Fruits[*]}
4
[aesteban@localhost ~]$ unset Fruits
[aesteban@localhost ~]$ echo ${!States[*]}
0 1 2
[aesteban@localhost ~]$

#associative arrays
[aesteban@localhost ~]$ declare -A INFO
[aesteban@localhost ~]$
[aesteban@localhost ~]$ INFO["name"]="Angel Esteban Cool"
[aesteban@localhost ~]$ echo ${INFO["name"]}
Angel Esteban Cool
[aesteban@localhost ~]$
[aesteban@localhost ~]$ INFO=([name]="Angel Cool" [website]="angelcool.net")
[aesteban@localhost ~]$
[aesteban@localhost ~]$ echo ${INFO["website"]}
angelcool.net
[aesteban@localhost ~]$


Loops
[aesteban@localhost ~]$ for i in $(seq 1 5); do echo This line corresponds to line $i.;done;
This line corresponds to line 1.
This line corresponds to line 2.
This line corresponds to line 3.
This line corresponds to line 4.
This line corresponds to line 5.
[aesteban@localhost ~]$
[aesteban@localhost ~]$
[aesteban@localhost ~]$ for i in {1..7}; do echo This is number $i.;done;
This is number 1.
This is number 2.
This is number 3.
This is number 4.
This is number 5.
This is number 6.
This is number 7.
[aesteban@localhost ~]$
[aesteban@localhost var]$ for i in `ls /var`;do echo $i;done;
...
[aesteban@localhost ~]$# looping through a list of servers
[aesteban@localhost ~]$for i in {1..5}; do ssh www-app0${i} "cd /var/www/html/barney.com && git pull origin live" ;done;


[ view entry ] ( 1406 views )   |  print article
Redis 101 - My Humble Notes. 
Basic Commands:
[acool@localhost ~]$ redis-server --version
Redis server v=2.8.18 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=94164e7f0a3c47c9
[acool@localhost ~]$
[acool@localhost ~]$ sudo systemctl start redis
[acool@localhost ~]$ redis-cli
127.0.0.1:6379>
127.0.0.1:6379> INFO
127.0.0.1:6379>
127.0.0.1:6379> SET fullName "Angel Cool"
OK
127.0.0.1:6379> GET fullName
"Angel Cool"
127.0.0.1:6379> DEL fullName
(integer) 1
127.0.0.1:6379> GET fullName
(nil)
127.0.0.1:6379> INCR attempts
(integer) 1
127.0.0.1:6379> INCR attempts
(integer) 2
127.0.0.1:6379> GET attempts
"2"
127.0.0.1:6379> SETNX attempts 25 //set if not exist
(integer) 0
127.0.0.1:6379> GET attempts
"2"
127.0.0.1:6379> SET token abc123
OK
127.0.0.1:6379> EXPIRE token 60
(integer) 1
127.0.0.1:6379> TTL token
(integer) 51
127.0.0.1:6379> TTL token
(integer) 44
127.0.0.1:6379> SETEX token 120 321abc //set & expire but atomic ;)
OK
127.0.0.1:6379> TTL token
(integer) 116
127.0.0.1:6379> TTL token
(integer) 114
127.0.0.1:6379> keys * //get all keys in redis
1) "friends"
2) "attempts"
3) "TOKEN"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> type friends // get key type, possible types: string, list, set, zset, hash.
list
127.0.0.1:6379> type attempts
string


Lists:
127.0.0.1:6379> RPUSH friends Daniel  //push a new value at the end of a list
(integer) 1
127.0.0.1:6379> RPUSH friends William
(integer) 2
127.0.0.1:6379> RPUSH friends Alex
(integer) 3
127.0.0.1:6379> RPUSH friends Rene
(integer) 4
127.0.0.1:6379> LRANGE friends 0 -1 //get all entries in list
1) "Daniel"
2) "William"
3) "Alex"
4) "Rene"
127.0.0.1:6379> LPUSH friends Elizabeth //push a new value at the start of a list
(integer) 5
127.0.0.1:6379> LLEN friends //returns the current lenght of a list
(integer) 5
127.0.0.1:6379> LRANGE friends 2 3 //returns a subset of a list
1) "William"
2) "Alex"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> LPOP friends //removes the first element from the list and returns it
"Elizabeth"
127.0.0.1:6379> RPOP friends //removes the last element from the list and returns it
"Rene"
127.0.0.1:6379>


Sets:
127.0.0.1:6379> SADD countries Canada
(integer) 1
127.0.0.1:6379> SADD countries Chile
(integer) 1
127.0.0.1:6379> SADD countries Brazil
(integer) 1
127.0.0.1:6379> SADD countries Mexico
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> SMEMBERS countries //output all members of a set
1) "Canada"
2) "Mexico"
3) "Brazil"
4) "Chile"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> SISMEMBER countries Mexico //test if a value is in a set
(integer) 1
127.0.0.1:6379> SREM countries Mexico //removes a value from a set
(integer) 1
127.0.0.1:6379> SISMEMBER countries Mexico
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> SMEMBERS cities
1) "London"
2) "Los Angeles"
3) "Merida"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> SUNION cities countries //combines sets and returns all members
1) "Merida"
2) "London"
3) "Canada"
4) "Brazil"
5) "Los Angeles"
6) "Chile"


Sorted Sets:
127.0.0.1:6379> ZADD hackers 1940 "Alan Kay"
(integer) 1
127.0.0.1:6379> ZADD hackers 1906 "Grace Hopper"
(integer) 1
127.0.0.1:6379> ZADD hackers 1953 "Richard Stallman"
(integer) 1
127.0.0.1:6379> ZADD hackers 1965 "Yukihiro Matsumoyo"
(integer) 1
127.0.0.1:6379> ZADD hackers 1983 "Angel Cool"
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> ZRANGE hackers 2 3 WITHSCORES
1) "Richard Stallman"
2) "1953"
3) "Yukihiro Matsumoyo"
4) "1965"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> ZADD hackers 1980 "Karla Cool"
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> ZRANGE hackers 0 -1 WITHSCORES //all scores, see how it's sorted by score (date of birth)
1) "Grace Hopper"
2) "1906"
3) "Alan Kay"
4) "1940"
5) "Richard Stallman"
6) "1953"
7) "Yukihiro Matsumoyo"
8) "1965"
9) "Karla Cool"
10) "1980"
11) "Angel Cool"
12) "1983"
127.0.0.1:6379>
127.0.0.1:6379> ZREVRANGE hackers 0 -1 withscores // reverse score
1) "Angel Cool"
2) "1983"
3) "Yukihiro Matsumoyo"
4) "1965"
5) "Richard Stallman"
6) "1953"
7) "Alan Kay"
8) "1940"
9) "Grace Hopper"
10) "1906"
127.0.0.1:6379>
127.0.0.1:6379> ZCOUNT hackers -inf +inf // returns the number of items in zset
(integer) 5
127.0.0.1:6379>
127.0.0.1:6379> ZREMRANGEBYSCORE hackers 1940 1960
(integer) 2


Hashes
127.0.0.1:6379> HSET user:1000 firstName Angel
(integer) 1
127.0.0.1:6379> HSET user:1000 lastName Cool
(integer) 1
127.0.0.1:6379> HSET user:1000 website angelcool.net
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> HGET user:1000 firstName
"Angel"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> HMSET user:2000 firstName Richard lastName Stallman website stallman.org
OK
127.0.0.1:6379>
127.0.0.1:6379> HGET user:2000 website
"stallman.org"
127.0.0.1:6379>
127.0.0.1:6379> HGETALL user:2000
1) "firstName"
2) "Richard"
3) "lastName"
4) "Stallman"
5) "website"
6) "stallman.org"
127.0.0.1:6379>
127.0.0.1:6379>


[ view entry ] ( 1447 views )   |  print article
Properly escaping a double quote in CSV 
Amazing trick. This is one of the first thing to try if your CSV spreadsheet is not rendering how you expect.

Original Question:
======================================================
I have a line like this in my CSV:

"Samsung U600 24"","10000003409","1","10000003427"

Quote next to 24 is used to express inches, while the quote just next to that quote closes the field. I'm reading the line with fgetcsv but the parser makes a mistake and reads the value as:

Samsung U600 24",10000003409"

I tried putting a backslash before the inches quote, but then I just get a backslash in the name:

Samsung U600 24\"

Is there a way to properly escape this in the CSV, so that the value would be Samsung U600 24" , or do I have to regex it in the processor?
======================================================


Answer:
======================================================
Use 2 quotes:

"Samsung U600 24"""
======================================================

http://stackoverflow.com/questions/1780 ... ote-in-csv

[ view entry ] ( 1507 views )   |  print article
HTML 5: Drawing an image from a data URL to a canvas  
http://jsfiddle.net/m4msmtdk/9/

if it's not fun why do it ? -ben & jerry ice cream


<canvas id="myCanvasNotYours"></canvas>

<script>

var myCanvas = document.getElementById('myCanvasNotYours');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
//alert(img.width);
myCanvas.width = img.width
myCanvas.height = img.height
ctx.drawImage(img,0,-20); // Or at whatever offset you like
};
img.src = 'data:image/png;base64,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';

</script>


[ view entry ] ( 1580 views )   |  print article
Postfix: SMTP forwarding based on sender 
Postfix: sender-dependent SASL authentication — relay to multiple SMTP hosts, or relay to the same host but authenticate as different users (e.g., two Gmail accounts)

I would like to send mail from two different Gmail accounts using Postfix.

As a concrete example, here's how to set up two Gmail accounts (only relevant sections of the config files are listed below):

/etc/postfix/main.cf:
# sender-dependent sasl authentication
smtp_sender_dependent_authentication = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

# default relayhost setting
relayhost = [smtp.gmail.com]:587

# smtp authentication settings
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_use_tls = yes
smtp_tls_security_level = encrypt

/etc/postfix/sasl_passwd:
# per-sender authentication
account1[@]gmail.com account1[@]gmail.com:passwd1
account2[@]gmail.com account2[@]gmail.com:passwd2

# default relayhost
[smtp.gmail.com]:587 default_account[@]gmail.com:default_passwd

/etc/postfix/sender_relay:
account1[@]gmail.com [smtp.gmail.com]:587
account2[@]gmail.com [smtp.gmail.com]:587


Create maps:
postmap sasl_passwd sender_relay


Restart postfix and test:

To send an email from account1[@]gmail.com, use sendmail with the -f sender option (set the envelope sender address):

sendmail -f account1[@]gmail.com -t <<EOF
To: barney[@]example.net
Subject: Hey, I successfully configured Postfix with sender-dependent SASL authentication!
Content-type: text/html

<b>Isn't this awesome?</b>
EOF


as of 2/2015:
https://gist.github.com/zmwangx/2c56aa32be68daf48c2f

[ view entry ] ( 1542 views )   |  print article
Node.js: Creating a new project with Express framework 
// install express globally
$npm install -g express-generator

// create a new project using handlebars for views
$express -hbs "node-chat"

// cd into "node-chat" and execute:
$npm install

// add suport for socket.io
$npm install socket.io --save


// output versions
[acool@localhost node-chat]$ node --version
v0.10.33
[acool@localhost node-chat]$ npm --version
1.3.6
[acool@localhost node-chat]$ express --version
4.11.1

// make sure daemon (dev only) is installed and run:
// (I think you can also do npm start or node bin/www)
[acool@localhost node-chat]$ nodemon bin/www

// finally go to browser and type http://localhost:3000
// ...socket.io sample to come.


[ view entry ] ( 1447 views )   |  print article

<<First <Back | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Next> Last>>


2024 By Angel Cool