Wednesday 1 January 2020

Django Learning Part 1

Started learning Django to build web applications.

Install Django in a virtual python environment

Prerequisite: Linux machine with python3 installed.
1) if virtualenv is not already installed, Install it using below command
 
    Let's assume, below is the working directory
    /home/<user_name>/python_learning/django/

    pip3 install virtualenv

2) virtualenv -p /usr/bin/python3 django_env
This creates a virtual environment by name django_env.

3) Activate the virtualenv using below command
    source django_env/bin/activate

4) Install django in the virtual environment which we just created.
 pip3 install django

5) Verify django is installed succesfully
    python -m django --version

   This command shall display the version of the django.

6) django installs command line utility by name "django-admin"

7) Execute below command to create first website
    "django-admin startproject <project_name>

Resources:
https://www.youtube.com/watch?v=UmljXZIypDc&list=PL-osiE80TeTtoQCKZ03TU5fNfx2UY6U4p&index=1



Saturday 15 June 2019

Python2 to Python3 migration few issues identified

In this post, I have listed below few of the python issues while migrating from python 2 to python3

Install python3-tools package to get 2to3 script.

Use 2to3 script to convert all python2 source code to python3.

1) Change in subprocess module functions output

Following program fails in python3.

cat test_file
COMPANY

cat test.py
import subprocess cmd = "cat test_file" out = subprocess.check_output(cmd, shell=True) print(out)
if "NO" in out:     print("YES") else:     print("NO")
Above program works fine in python2. But it fails in python3 with below exception
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    if "NO" in out:
TypeError: a bytes-like object is required, not 'str'

In python3, by default output returned is in encoded bytes. So in above example, out variable is of type bytes and "NO" is a string.
To solve above problem,  universal_newlines to True (This argument has to be passed to check_ouput function.

In general, most of the functions available in subprocess module return bytes. So better to include argument "universal_newlines=True" to get output in string format.

2) Change in socket module
most of the functions in socket module accepts arguments in bytes format in python3, whereas arguments are passed as strings in python2.
Ex:
python2 → sock.sendall(message)
python3 → sock.sendall(message.encode('utf-8'))
python2 → client_socket.send(response_msg)
python3 → client_socket.send(response_msg.encode('utf-8'))

3) read() function returns bytes class type when file is read in binary mode. 
 
[root@sandeep ~]# cat binary_data.py
with open("random", "wb") as f:
    f.write(b'COMPANY')

out = None
with open("random", "rb") as f:
    out = f.read()

print(out)
print(out.decode())
print(type(out))

Output in Python3
root@sandeep ~]# python3 binary_data.py
b'COMPANY'
COMPANY
<class 'bytes'>

Output in Python2
[root@sandeep ~]# python2 binary_data.py
COMPANY
COMPANY
<type 'str'>

In case of python3,  If the file reading is in binary mode, then the output returned by read() function is in bytes object type.

b’COMPANY’

so the code has to explicitly decode the value to string for comparison.

if out == "COMPANY":

Above if condition fails in python3 if it is not decoded explicitly. 

I will update this post as and when I encounter new migration issues. Comment if you have guys have found any other issues with example.

Monday 10 June 2019

NamedTuple in python

Today I learnt about python container like dictionaries called "namedtuples" which is present in module called "collections"

Some of the operations performed on namedtuples are
  1. Access by index
  2. Access by keyname
  3. Access by getattr

Conversion Operations supported
  1. _make()  - returns namedtuple() from iterable passed as an argument.
  2. _asdict() - returns OrderedDict() as constructed from the mapped values of namedtuple()
  3. ** -  This operator is used to convert a dictionary into the namedtuple().

Extra Operations
  1. _fields gives the information about all the key names declared. 

Example Code:


"""

Below examples discusses about namedtuple from collections module

"""

import collections


#Declaring a namedtuple
employee = collections.namedtuple("Employee", ["Name", "Age", "DOB"])



#Adding Values
emp = employee("Johnny Depp", "35", "02011983")


#initializing iterable
ex_list = ["Abraham", "24", "20091994"]


#initializing dict
ex_dict = {"Name" : "Moti", "Age" : 29, "DOB" : "16091987"}


#Below 3print statements print Same output

print(emp.Name) #Access by key
print(emp[0]) #Access by index
print(getattr(emp, "Name")) #Access via getattr



#using _make() to return namedtuple()
print ("The namedtuple instance using iterable is : ")
print(employee._make(ex_list))


#using _asdict() to return an OrderedDict()
print("The OrderedDict instance using namedtuple is :")
print(emp._asdict())



#using ** operator to return namedtuple from dictionary
print("The namedtuple instance from dict is :")
print(employee(**ex_dict))


#print fields of the named tuple
print(emp._fields)