Featured

TechBytes on Linux

This is a growing list of Linux commands which might come handy for the of Linux users. 1. Found out i had to set the date like this: ...

Saturday, August 23, 2014

Method argument Pass by Value & Pass by Reference behavior in Python

This is a very important concept in Python where the behavior of pass by value & pass by reference varies with lists compared to immutable data types like strings.

Source http://www.python-course.eu/passing_arguments.php

Parameter Passing

"call by value" and "call by name"

Parameterübergabe als StaffellaufThe most common evaluation strategy when passing arguments to a function has been call by value and call by reference:
  • Call by Value
    The most common strategy is the call-by-value evaluation, sometimes also called pass-by-value. This strategy is used in C and C++ for example. In call-by-value, the argument expression is evaluated, and the result of this evaluation is bound to the corresponding variable in the function. So, if the expression is a variable, a local copy of its value will be used, i.e. the variable in the caller's scope will be unchanged when the function returns.
  • Call by Reference
    In call-by-reference evaluation, which is also known as pass-by-reference, a function gets an implicit reference to the argument, rather than a copy of its value. As a consequence, the function can modify the argument, i.e. the value of the variable in the caller's scope can be changed. The advantage of call-by-reference consists in the advantage of greater time- and space-efficiency, because arguments do not need to be copied. On the other hand this harbours the disadvantage that variables can be "accidentally" changed in a function call. So special care has to be taken to "protect" the values, which shouldn't be changed.
    Many programming language support call-by-reference, like C or C++, but Perl uses it as default.
In ALGOL 60 and COBOL has been known a different concept, which was called call-by-name, which isn't used anymore in modern languages.

and what about Python?

Humpty DumptyThere are books which call the strategy of Python call-by-value and others call it call-by-reference. You may ask yourself, what is right. 

Humpty Dumpty supplies the explanation: 

--- "When I use a word," Humpty Dumpty said, in a rather a scornful tone, "it means just what I choose it to mean - neither more nor less."
--- "The question is," said Alice, "whether you can make words mean so many different things."
--- "The question is," said Humpty Dumpty, "which is to be master - that's all." 
Lewis Carroll, Through the Looking-Glass

To come back to our initial question what is used in Python: The authors who call the mechanism call-by-value and those who call it call-by-reference are stretching the definitions until they fit. 
Correctly speaking, Python uses a mechanism, which is known as "Call-by-Object", sometimes also called "Call by Object Reference" or "Call by Sharing".

ParamterübergabeIf you pass immutable arguments like integers, strings or tuples to a function, the passing acts like call-by-value. The object reference is passed to the function parameters. They can't be changed within the function, because they can't be changed at all, i.e. they are immutable. It's different, if we pass mutable arguments. They are also passed by object reference, but they can be changed in place in the function. If we pass a list to a function, we have to consider two cases: Elements of a list can be changed in place, i.e. the list will be changed even in the caller's scope. If a new list is assigned to the name, the old list will not be affected, i.e. the list in the caller's scope will remain untouched. 

First, let's have a look at the integer variables. The parameter inside of the function remains a reference to the arguments variable, as long as the parameter is not changed. As soon as a new value will be assigned to it, Python creates a separate local variable. The caller's variable will not be changed this way: 
def ref_demo(x):
    print "x=",x," id=",id(x)
    x=42
    print "x=",x," id=",id(x)
ParamterübergabeIn the example above, we used the id() function, which takes an object as a parameter. id(obj) returns the "identity" of the object "obj". This identity, the return value of the function, is an integer which is unique and constant for this object during its lifetime. Two different objects with non-overlapping lifetimes may have the same id() value. 

If you call the function ref_demo() - like we do in the green block further down - we can check with the id() function what happens to x. We can see that in the main scope, x has the identity 41902552. In the first print statement of the ref_demo() function, the x from the main scope is used, because we can see that we get the same identity. After we have assigned the value 42 to x, x gets a new identity 41903752, i.e. a separate memory location from the global x. So, when we are back in the main scope x has still the original value 9. 

This means, that Python initially behaves like call-by-reference, but as soon as we are changing the value of such a variable, Python "switches" to call-by-value.
>>> x = 9
>>> id(x)
41902552
>>> ref_demo(x)
x= 9  id= 41902552
x= 42  id= 41903752
>>> id(x)
41902552
>>> 

Side effects

A function is said to have a side effect if, in addition to producing a value, it modifies the caller's environment in other ways. For example, a function might modify a global or static variable, modify one of its arguments, raise an exception, write data to a display or file and so on. 

In many cases these side effects are wanted, i.e. they are part of the functions specification. But in other cases, they are not wanted , they are hidden side effects. In this chapter we are only interested in the side effects, which change global variables, which have been passed as arguments to a function. 
Let's assume, we are passing a list to a function. We expect, that the function is not changing this list. First let's have a look at a function which has no side effects. As a new list is assigned to the parameter list in func1(), a new memory location is created for list and list becomes a local variable.
>>> def func1(list):
...     print list
...     list = [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func1(fib)
[0, 1, 1, 2, 3, 5, 8]
[47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8]
>>> 
This changes drastically, if we include something in the list by using +=. To show this, we have a different function func2() in the following example:
>>> def func2(list):
...     print list
...     list += [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func2(fib)
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>> 
The user of the function can prevent this by passing a copy to the function. In this case a shallow copy is sufficient:
>>> def func2(list):
...     print list
...     list += [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func2(fib[:])
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8]
>>> 

Command Line Arguments

It's possible to write Python scripts using command line arguments. If you call a Python script from a shell, the arguments are placed after the script name. The arguments are separated by spaces. Inside of the script these argumetns are accessible through the list variable sys.argv. The name of the script is included in this list sys.argv[0]. sys.argv[1] contains the first parameter, sys.argv[2] the second and so on. 
The following script (arguments.py) prints all arguments: 
 # Module sys has to be imported:
import sys                

# Iteration over all arguments:
for eachArg in sys.argv:   
        print eachArg
Example call to this script:
python argumente.py python course for beginners
This call creates the following output:
argumente.py
python
course
for
beginners

Variable Length of Parameters

We will introduce now functions, which can take an arbitrary number of arguments. Those who have some programming background in C or C++ know this from the varargs feature of these languages. The asterisk "*" is used in Python to define a variable number of arguments. The asterisk character has to precede a variable identifier in the parameter list.
>>> def varpafu(*x): print(x)
... 
>>> varpafu()
()
>>> varpafu(34,"Do you like Python?", "Of course")
(34, 'Do you like Python?', 'Of course')
>>> 
We learn from the previous example, that the arguments passed to the function call of varpafu() are collected in a tuple, which can be accessed as a "normal" variable x within the body of the function. If the function is called without any arguments, the value of x is an empty tuple. 

Sometimes, it's necessary to use positional parameters followed by an arbitrary number of parameters in a function definition. This is possible, but the positional parameters always have to precede the arbitrary parameters. In the following example, we have a positional parameter "city", - the main location, - which always have to be given, followed by an arbitrary number of other locations: 
>>> def locations(city, *other_cities): print(city, other_cities)
... 
>>> locations("Paris")
('Paris', ())
>>> locations("Paris", "Strasbourg", "Lyon", "Dijon", "Bordeaux", "Marseille")
('Paris', ('Strasbourg', 'Lyon', 'Dijon', 'Bordeaux', 'Marseille'))
>>> 

Exercise

Write a function which calculates the arithmetic mean of a variable number of values.

Solution

def arithmetic_mean(x, *l):
    """ The function calculates the arithmetic mean of a non-empty
        arbitrary number of numbers """
    sum = x
    for i in l:
        sum += i

    return sum / (1.0 + len(l))
You might ask yourself, why we used both a positional parameter "x" and the variable parameter "*l" in our function definition. We could have only used *l to contain all our numbers. The idea is, that we wanted to enforce, that we always have a non-empty list of numbers. This is necessary to prevent a division by zero error, because the average of a non-empty list of numbers is not defined. 

In the following interactive Python session, we can learn how to use this function. We assume that the function arithmetic_mean is saved in a file called statistics.py.
>>> from statistics import arithmetic_mean
>>> arithmetic_mean(4,7,9)
6.666666666666667
>>> arithmetic_mean(4,7,9,45,-3.7,99)
26.71666666666667
This works fine, but there is a catch. What if somebody wants to call the function with a list, instead of a variable number of numbers, as we have shown above? We can see in the following, that we raise an error, as most hopefully, you might expect:
>>> l = [4,7,9,45,-3.7,99]
>>> arithmetic_mean(l)
Traceback (most recent call last):
  File "", line 1, in 
  File "statistics.py", line 8, in arithmetic_mean
    return sum / (1.0 + len(l))
TypeError: unsupported operand type(s) for /: 'list' and 'float'
The rescue is using another asterisk:
>>> arithmetic_mean(*l)
26.71666666666667
>>> 


* in Function Calls

A * can appear in function calls as well, as we have just seen in the previous exercise: The semantics is in this case "inverse" to a star in a function definition. An argument will be unpacked and not packed. In other words, the elements of the list or tuple are singularized:
>>> def f(x,y,z):
...     print(x,y,z)
... 
>>> p = (47,11,12)
>>> f(*p)
(47, 11, 12)
There is hardly any need to mention that this way of calling our function is more comfortable the the following one:
>>> f(p[0],p[1],p[2])
(47, 11, 12)
>>> 
Additionally to being less comfortable, the previous call (f(p[0],p[1],p[2])) doesn't work in the general case, i.e. lists of unknown lengths. "Unknown" mean, that the length is only known at runtime and not when we are writing the script.

Arbitrary Keyword Parameters

There is also a mechanism for an arbitrary number of keyword parameters. To do this, we use the double asterisk "**" notation:
>>> def f(**args):
...     print(args)
... 
>>> f()
{}
>>> f(de="Germnan",en="English",fr="French")
{'fr': 'French', 'de': 'Germnan', 'en': 'English'}
>>> 

Double Asterisk in Function Calls

The following example demonstrates the usage of ** in a function call:
>>> def f(a,b,x,y):
...     print(a,b,x,y)
...
>>> d = {'a':'append', 'b':'block','x':'extract','y':'yes'}
>>> f(**d)
('append', 'block', 'extract', 'yes')
and now in combination with *:
>>> t = (47,11)
>>> d = {'x':'extract','y':'yes'}
>>> f(*t, **d)
(47, 11, 'extract', 'yes')
>>> 

Thursday, June 26, 2014

Wednesday, May 21, 2014

OpenStack Keystone Issue with Update of User’s Password – Havana

OpenStack Keystone Update User’s Password – Havana

It took me a while to figure out how to update a user’s password via the API in Keystone.  All of the documentation seems to be incorrect.  I finally had to take a packet trace of the keystone CLI performing a password update and looking at that before I got the correct API endpoint and what to send to the server.  It turns out to be a PUT request and not like most of their documentation saying it is is a POST request.  Which would make sense since PUT is for updating.
Here is the cURL command:
curl -X PUT \
-H “X-Auth-Token:” \
-H “Content-type: application/json” \
-d ‘{“user”: {“password”: “new_password”, “id”: ““}}’\

Tuesday, December 4, 2012

What is the optimum way to find the middle node in a single linked list using C?


What is the optimum way to find the middle node in a single linked list using C?


    There are two ways
Method 1
1- Iterate through the link list to find the number of nodes in it (say n)
2- Start from the root of the list and travel as far as n/2

The other method is a bit tricky
Method 2
1- Start with two pointers both pointing to root
2- Now make one traverse the link list one node at a time
3- Make the other traverse the link list 2 nodes at a time
At the time, the 2nd pointer reaches the end, the 1st pointer would only have reached the mid

The 1st method is optimized for memory and the 2nd one for concurrent traversal and speed

Monday, August 6, 2012

TechBytes on Linux


This is a growing list of Linux commands which might come handy for the of Linux users.

1. Found out i had to set the date like this:
# date -s 2007.04.08-22:46+0000

2. Mounting
sudo mount -t cifs // < pingable_host_or_ip > / < win_share_name > /build -o user=,domain=,uid=string,gid=string

3. To install linux packages from internet (ubuntu only)
apt-get install

4. To determine what ports the machine is currently listening on
netstat -an | grep -i listen | less

5. Find in files in Linux
find . | xargs grep 'string' -sl


Find file names with a pattern & delete them


find . -name "IMG_*(1).JPG" -delete
6. To become superuser/root
sudo -i

7. To find a running process using name

ps -aef | grep "searchstring"

8. Alt + F2 opens run window in RHEL

9. To access windows share from linux
smb:///d$

10. To know the last reboot date & time
$ last reboot | head -1

11. To install RPM packages in RHEL
rpm -ivh

12. To un-install RPM package in RHEL
rpm -e

13. To display Linux Kernel version
uname --all

14. To list out the Linux partitions
cat /proc/partitions

15. To list of all writable storage devices in Linux
fdisk -l

16. Installing software from sources in Linux
http://www.tuxfiles.org/linuxhelp/softinstall.html

17. The -T option in the df command displays the file system type.
df -T

18. Open current directory from within the terminal
xdg-open .


18. Find out details about the CPU such as speed, type, no of cores etc
cat /proc/cpuinfo

19. Find out details about memory installed
cat /proc/meminfo
vmstat


20. To list out installed rpms
rpm -qa

21. To Disable firewall on RHEL 7.2
systemctl stop firewalld
systemctl status firewalld


22. Find out the Linux OS/Operating system version
a] /etc/*-release file.
b] lsb_release command.
c] /proc/version file.

23. Try this to reload your current shell
source ~/.profile


24. The following Linux commands can be used to search files by name.find /path -name *.txt
find /path -type f -name test.txt
find /path -name failed*.* -type f
find /path -type f -not -name “*.html”
find / -name “file.txt” -size +4M
find /dev/ -type b -name “sda*”


25. Scp commandThe SCP (Secure Copy Protocol) command is a powerful utility for securely transferring files and directories between two locations over a network. It leverages SSH (Secure Shell) for authentication and encryption, ensuring that both the files and passwords are protected during the transfer.
scp [OPTION] [user@]SRC_HOST:]file1 [user@]DEST_HOST:]file2OPTION: Various options to control the behavior of scp, such as specifying the SSH port, enabling compression, or copying directories recursively.
[user@]SRC_HOST:]file1: Path to the source file, including the user and host if the file is on a remote machine.
[user@]DEST_HOST:]file2: Path to the destination file, including the user and host if the file is on a remote machine.


26. Proxy configuration on Ubuntu Linux



apt-get, aptitude, etc. will not obey the environment variables when used normally with sudo. So separately configure them; create a file called 95proxies in /etc/apt/apt.conf.d/, and include the following:Acquire::http::proxy "http://myproxy.server.com:8080/"; Acquire::ftp::proxy "ftp://myproxy.server.com:8080/"; Acquire::https::proxy "https://myproxy.server.com:8080/";


27. Find in files
a. Find a string in a text file inside a gz file.
zgrep -i -H "pattern match" *.gz

b. Find a string in a folder path
grep -r "foo" /home/thisuser/bar/baz/*





28. Scanning scsi disks in RHEL

1.Finding the existing disk from fdisk.
[root@mylinz1 ~]# fdisk -l |egrep '^Disk' |egrep -v 'dm-' Disk /dev/sda: 21.5 GB, 21474836480 bytes

2.Find out how many SCSI controller configured. [root@mylinz1 ~]# ls /sys/class/scsi_host/host host0 host1 host2

In this case,you need to scan host0,host1 & host2.

3.Scan the SCSI disks using below command. [root@mylinz1 ~]# echo "- - -" > /sys/class/scsi_host/host0/scan [root@mylinz1 ~]# echo "- - -" > /sys/class/scsi_host/host1/scan [root@mylinz1 ~]# echo "- - -" > /sys/class/scsi_host/host2/scan

4.Verify if the new disks are visible or not. [root@mylinz1 ~]# fdisk -l |egrep '^Disk' |egrep -v 'dm-' Disk /dev/sda: 21.5 GB, 21474836480 bytes Disk /dev/sdb: 1073 MB, 1073741824 bytes Disk /dev/sdc: 1073 MB, 1073741824 bytes

From Redhat Linux 5.4 onwards, redhat introduced “/usr/bin/rescan-scsi-bus.sh” script to scan all the SCSI bus and update the SCSI layer to reflect new devices.
Install it using yum -y install sg3_utils command.
But most of the time,script will not be able to scan new disks and you need go with echo command.
Useful link on how to configure iSCSI volumes
https://www.cyberciti.biz/tips/rhel-centos-fedora-linux-iscsi-howto.html 29. Repeat the command every n seconds
watch -n 5 ls -lh <filepath>
or
# Source - https://stackoverflow.com/a
# Posted by mikhail, modified by community. See post 'Timeline' for change history
# Retrieved 2026-01-27, License - CC BY-SA 3.0


while true; do ls -lh <filepath> ; sleep 5; done


30. Reload the history file


The following will append the contents of file.txt to the current in-memory history list:history -r file.txt


You can optionally run history -c before this to clear the in-memory history.




how to reload the default history file, which it turns out is just history -r without the file path.






Popular Posts