Monthly Archives: June 2013

Don’t run some commands!

Let’s say you are working on a project with multiple computers and users. You may want that some commands work only on a restricted set of user accounts.

You may want to restrict a newbie from using dangerous commands that could harm the project files. A solution to implement this feature is as follows:

1. Make a directory for every user (do_not_run.$HOSTNAME)

2. Put shell scripts with the same name as the command to be blocked/restricted in the folder. Make these scripts print an error to the stderr that this operation is not permitted for the user.

echo -e “\aYou are not allowed to perform this action.” 1>&2

\a or 07 provide an audible ring to notify users of error

3. Update the PATH environment variable to include your directory BEFORE the directory in which the restricted commands are placed.

Advertisements

Standard Error and Standard Output

The echo command prints to standard output. However we know that it is good practice to redirect the error messages to standard error, lest the errors be redirected along with the output.

So, many languages provide features for writing to the standard error. (example: sys.stderr for Python)

For bash users, it is possible to redirect the echo output to standard error. We use the 1>&2 operator.

$ echo “#Error: Invalid calculation” 1>&2

Remember, this works only with bourne shells

Get more file info!

The wc bash command gives more info on the contents of a file. A simple man command on wc (man wc) will give:

wc: print newline, word, and byte counts for each file

I create a file named file1

wc file1

This command gives a weird output like:

 2 5   25 file1

Here 2 is the number of newline characters in the file

5 is the number of space separated words

25 is the size of file in bytes (= number of characters in the file iff each character = 1 byte)

file1 is the name of the file under consideration

Here’s a nifty trick.

$ printf ‘The %4$s file has %2$03s words over %1$s lines. Size: %3$s bytes.\n’ `wc file1`

  

This outputs

The file1 file has 025 words over 2 lines. Size: 25 bytes

$

Vector class

Was working on a graphics oriented project, for which I created a separate Vector class in C++ (although you can use Boost C++ libraries for the same).

The code is available at:

https://www.dropbox.com/s/ifo9mua3ig6weyq/Vector.cpp

You can create objects of Vec3 with coordinates specified as integers, floats or doubles, as this is a template class for the same.

Python equivalent of uniq

Run the given command:

$ man uniq

We get the following result:

uniq: report or omit multiple lines

Python has a way to implement this functionality. Of course one can do the following:

import commands

cmd = < # uniq command usage >

status, output = commands.getstatusoutput(cmd)

Using commands allows us to run any bash command from within Python.

The itertools module provides us with group by, which can be used to give results similar to uniq.

It can group “adjacent duplicate elements” together.

For the following code, an input of HHiiiii! will yield an output of

[(2,’H’), (5,’i’), (1,’!’)]

https://www.dropbox.com/s/1lpc8a7qnx6vll0/rle.py

itertools.islice

Iterators are very important to Python and their use is found in many programs. The itertools module is provided in the standard library to implement common iterator patterns.

It is written in the C language and hence is the most optimised iterator module out there.

islice can be used to extract data from a particular point in a data stream (like text from the Standard Input). It returns an iterator that works with a sub-group of a sequence.

Its syntax can be looked up with

$ pydoc itertools.islice

https://www.dropbox.com/s/p7hg7e9qz319v71/findBigWords.py

PS: Enabled use of Nautilus via command line…

I can now open folders with nautilus ~/bin/

itertools.tee


Using tee we can run several iterators over a sequence. tee returns more than 1 iterables to be used.

itertools.tee(sequence,n) where sequence is to be iterated over. n is the number of iterables to be created by tee.

coroutines and genexp

Co-routines are functions that can be stopped and resumed and can take data from multiple entry points. It is  very similar to “threading”. However in threading, the various threads work in a pre-emptive manner, hence there is a chance of resource locking.

The multitask module (can be installed with easy_install multitask) is a way of implementing co-routines. Another way is to use greenlet library.

>>> import multitask as m

>>> def fun1():

for i in range(2):

print ‘Fun 1 %d’ % i

yield i

>>> def fun2():

for i in range(4):

print ‘Fun 2 %d’ % i

yield i

>>> m.add(fun1())

>>> m.add(fun2())

>>> m.run()

Fun1 0

Fun2 0

Fun1 1

Fun2 1

Fun2 2

Fun2 3

>>>

>>>

Generator Expressions


These are very similar to list comprehension. They are a way to iterate over a generator in fewer lines of code.

* Use parenthesis () instead of square brackets []

* Replace yield

>>> i = (a**3 for a in range(10) if a % 2 != 0) # cubes of all odd numbers < 10

>>> i

< generator object <genexpr> at 0xb77374 >

>>> i.next()

1

>>>

>>> i.next()

27

>>>

>>> i.next()

125

>>>

>>> for e in i:

print e

343

729

>>>

Genexps yield values one at a time, so the entire sequence is NOT calculated at once (ahead of time). Thus the CPU assigns them a lower priority, so that more resources can be devoted to intensive tasks.

Opening new folders in CentOS without opening new windows!

Opening new folders in CentOS without opening new windows!

Nautilus -> Edit -> Preferences -> Behavior -> Always open in browser

Tagged

sending data to generator objects

The send() method of a generator object can be used to provide data to the yield in a generator.

>>> def answerer():

print “Enter a string: “

while True:

ans = (yield)

if ‘good’ in ans:

print “That’s positive !”

elif ‘bad’ in ans:

print “That’s negative !”

else:

print “I don’t know !”

>>> f = answerer()

>>> f.next()

Enter a string:

>>> f.send(‘I am good’)

That’s positive

>>> f.send(‘You are bad’)

That’s negative

>>> f.send(‘Hi!’)

I don’t know

Improving efficiency of staged transformations

Staged transformations are transformations applied to a set of data in stages.

Lets say I want the following to happen.

Given a list [1,2,3,4,5,…, 100]

1. Square all odd numbers

2. Cube all even numbers

3. Let the numbers from the above calculations should be stored in 1 list.

Hence we should get [1, 8, 9, 64, 25, …]

4. Now in this list add 3 to all even numbers and 2 to all odd numbers

Final o/p: [3,11,11,67,27,…]

We can simplify the code a lot…

https://www.dropbox.com/s/enzdl6h7anh5llm/staged.py