Pages

Saturday, March 18, 2017

Python interview questions and answers


What is Python?
Python is a high-level, interpreted, interactive and object-oriented scripting language. Python is designed to be highly readable. It uses English keywords frequently where as other languages use punctuation, and it has fewer syntactical constructions than other languages.

What is the purpose of PYTHONPATH environment variable?
PYTHONPATH - It has a role similar to PATH. This variable tells the Python interpreter where to locate the module files imported into a program. It should include the Python source library directory and the directories containing Python source code. PYTHONPATH is sometimes preset by the Python installer.

What is the purpose of PYTHONSTARTUP environment variable?
PYTHONSTARTUP - It contains the path of an initialization file containing Python source code. It is executed every time you start the interpreter. It is named as .pythonrc.py in Unix and it contains commands that load utilities or modify PYTHONPATH.

Is python a case-sensitive language?
Yes! Python is a case sensitive programming language.

What are the supported data types in Python?
Python has five standard data types −
Numbers
String
List
Tuple
Dictionary

What are tuples in Python?
A tuple is another sequence data type that is similar to the list. A tuple consists of a number of values separated by commas. Unlike lists, however, tuples are enclosed within parentheses.

What is the difference between tuples and lists in Python?
The main differences between lists and tuples are − Lists are enclosed in brackets ( [ ] ) and their elements and size can be changed, while tuples are enclosed in parentheses ( ( ) ) and cannot be updated. Tuples can be thought of as read-only lists.

What are Python's dictionaries?
Python's dictionaries are kind of hash table type. They work like associative arrays or hashes found in Perl and consist of key-value pairs. A dictionary key can be almost any Python type, but are usually numbers or strings. Values, on the other hand, can be any arbitrary Python object.

How will you create a dictionary in python?
Dictionaries are enclosed by curly braces ({ }) and values can be assigned and accessed using square braces ([]).

dict = {}
dict['one'] = "This is one"
dict[2]     = "This is two"
tinydict = {'name': 'john','code':6734, 'dept': 'sales'}

How will you get all the keys from the dictionary?
Using dictionary.keys() function, we can get all the keys from the dictionary object.
print dict.keys()   # Prints all the keys

How will you get all the values from the dictionary?
Using dictionary.values() function, we can get all the values from the dictionary object.
print dict.values()   # Prints all the values

How will you convert a string to an int in python?
int(x [,base]) - Converts x to an integer. base specifies the base if x is a string.

How will you convert a string to a long in python?
long(x [,base] ) - Converts x to a long integer. base specifies the base if x is a string.

How will you convert a string to a float in python?
float(x) − Converts x to a floating-point number.

How will you convert a object to a string in python?
str(x) − Converts object x to a string representation.

How will you convert a object to a regular expression in python?
repr(x) − Converts object x to an expression string.

How will you convert a String to an object in python?
eval(str) − Evaluates a string and returns an object.

How will you convert a string to a tuple in python?
tuple(s) − Converts s to a tuple.

How will you convert a string to a list in python?
list(s) − Converts s to a list.

How will you convert a string to a set in python?
set(s) − Converts s to a set.

How will you create a dictionary using tuples in python?
dict(d) − Creates a dictionary. d must be a sequence of (key,value) tuples.

How will you convert an integer to a character in python?
chr(x) − Converts an integer to a character.

How will you convert a single character to its integer value in python?
ord(x) − Converts a single character to its integer value.

How will you convert an integer to hexadecimal string in python?
hex(x) − Converts an integer to a hexadecimal string.

What is the purpose of // operator?
// Floor Division − The division of operands where the result is the quotient in which the digits after the decimal point are removed.

What is the purpose of is operator?
is − Evaluates to true if the variables on either side of the operator point to the same object and false otherwise. x is y, here is results in 1 if id(x) equals id(y).

What is the purpose break statement in python?
break statement − Terminates the loop statement and transfers execution to the statement immediately following the loop.

What is the purpose continue statement in python?
continue statement − Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.

What is the purpose pass statement in python?
pass statement − The pass statement in Python is used when a statement is required syntactically but you do not want any command or code to execute.

How can you get a random number in python?
random() − returns a random float r, such that 0 is less than or equal to r and r is less than 1.

How will you capitalizes first letter of string?
capitalize() − Capitalizes first letter of string.

How will you check in a string that all characters are digits?
isdigit() − Returns true if string contains only digits and false otherwise.

How will you check in a string that all characters are alphanumeric?
isalnum() − Returns true if string has at least 1 character and all characters are alphanumeric and false otherwise.

How will you check in a string that all characters are in lowercase?
islower() − Returns true if string has at least 1 cased character and all cased characters are in lowercase and false otherwise.

How will you check in a string that all characters are numerics?
isnumeric() − Returns true if a unicode string contains only numeric characters and false otherwise.

How will you check in a string that all characters are whitespaces?
isspace() − Returns true if string contains only whitespace characters and false otherwise.

How will you check in a string that it is properly titlecased?
istitle() − Returns true if string is properly "titlecased" and false otherwise.

How will you check in a string that all characters are in uppercase?
isupper() − Returns true if string has at least one cased character and all cased characters are in uppercase and false otherwise.

How will you merge elements in a sequence?
join(seq) − Merges (concatenates) the string representations of elements in sequence seq into a string, with separator string.

How will you get the length of the string?
len(string) − Returns the length of the string.

How will you remove all leading whitespace in string?
lstrip() − Removes all leading whitespace in string.

How will you replace all occurrences of old substring in string with new string?
replace(old, new [, max]) − Replaces all occurrences of old in string with new or at most max occurrences if max given.

How will you remove all leading and trailing whitespace in string?
strip([chars]) − Performs both lstrip() and rstrip() on string.

How will you get titlecased version of string?
title() − Returns "titlecased" version of string, that is, all words begin with uppercase and the rest are lowercase.

What is the output of len([1, 2, 3])?
3.

What is the output of [1, 2, 3] + [4, 5, 6]?
[1, 2, 3, 4, 5, 6]

What is the output of ['Hi!'] * 4?
['Hi!', 'Hi!', 'Hi!', 'Hi!']

What is the output of 3 in [1, 2, 3]?
True

What is the output of for x in [1, 2, 3]: print x?
1 2 3

What is the output of L[2] if L = [1,2,3]?
3, Offsets start at zero.

What is the output of L[-2] if L = [1,2,3]?
L[-1] = 3, L[-2]=2, L[-3]=1

What is the output of L[1:] if L = [1,2,3]?
2, 3, Slicing fetches sections.

How will you compare two lists?
cmp(list1, list2) − Compares elements of both lists.

How will you get the length of a list?
len(list) − Gives the total length of the list.

How will you get the max valued item of a list?
max(list) − Returns item from the list with max value.

How will you get the min valued item of a list?
min(list) − Returns item from the list with min value.

How will you get the index of an object in a list?
list.index(obj) − Returns the lowest index in list that obj appears.

How will you remove last object from a list?
list.pop(obj=list[-1]) − Removes and returns last object or obj from list.

How will you remove last object from a list?
list.pop(obj=list[-1]) − Removes and returns last object or obj from list.

How will you remove an object from a list?
list.remove(obj) − Removes object obj from list.

How will you reverse a list?
list.reverse() − Reverses objects of list in place.

How will you sort a list?
list.sort([func]) − Sorts objects of list, use compare func if given.

## multiple assignment
>>> target_color_name = first_color_name = 'FireBrick'
>>> id(target_color_name) == id(first_color_name)
True
>>> print(target_color_name)
FireBrick
>>> print(first_color_name)
FireBrick
>>>

## word count
import sys

def count_words(filename):
    results = dict()
    with open(filename, 'r') as f:
        for line in f:
            for word in line.split():
                results[word] = results.setdefault(word, 0) + 1

    for word, count in sorted(results.items(), key=lambda x: x[1]):
        print('{} {}'.format(count, word))

count_words(sys.argv[1])

or

def count_words(file_path):
    try:
        with open(file_path, 'r') as file:
            text = file.read()
            word_count = len(text.split())
            print("Number of words:", word_count)
    except FileNotFoundError:
        print("File not found!")
    except Exception as e:
        print("An error occurred:", e)

# Example usage:
file_path = 'sample.txt'  # Replace 'sample.txt' with the path to your file
count_words(file_path)


## word list
from urllib.request import urlopen

with urlopen('http://sixty-north.com/c/t.txt') as story:
    story_words = []
    for line in story:
        line_words = line.split()
        for word in line_words:
            story_words.append(word)

print(story_words)

"""Demonstrate scoping."""

count = 0

def show_count():
    print("count = ", count)

def set_count(c):
    global count
    count = c
 
"""Module for demonstrating files."""
import sys
def main(filename):
  f = open(filename, mode='rt', encoding='utf-8')
  for line in f:
      sys.stdout.write(line)
  f.close()

if __name__ == '__main__':
  main(sys.argv[1])

## Write a function to add two numbers
def add_numbers(*args):
    total = 0
    for a in args:
        total += a
    print (total)

add_numbers(3)
add_numbers(3, 42)


or

def add_numbers(num1, num2):
    return num1 + num2

# Example usage:
result = add_numbers(5, 7)
print("Result:", result)  # Output: 12



### How to un-pack arguments
def health_calculator(age, apples_ate, cigs_smoked):
    answer = (100-age) + (apples_ate * 3.5) - (cigs_smoked * 2)
    print(answer)

data = [27,20,0]
health_calculator(data[0],data[1],data[2])
health_calculator(*data)

# Program to find a magic number using break
magicNumber = 26
for n in range(101):
    if n is magicNumber:
        print(n,"is the magic number!")
        break
    else:
        print(n)
     
# Example of continue
numbersTaken = [2,5,12,33,17]
print ("Here are the numbers that are still available:")
for n in range(1,20):
    if n in numbersTaken:
        continue
    print(n)
 
## Example of default arg
def get_gender(sex='Unknown'):
    if sex is "m":
        sex = "Male"
    elif sex is "f":
        sex = "Female"
    print(sex)

get_gender
get_gender('f')
get_gender()

## Example of for
foods = ['apple', 'banana', 'grapes', 'mango']
for f in foods:
    print(f)
    print(len(f))
 
## function example
def cisco():
    print("Python, fucntions are cool!")
cisco()

def bitcoin_to_usd(btc):
    amount = btc*527
    print(amount)

bitcoin_to_usd(3.85)

## Example of if else
name = "Lucy"
if name is "nawraj":
    print("hey there Nawraj")
elif name is "Lucy":
    print("What's up Lucy")
elif name is "Sammy":
    print("What's up Sammy")
else:
    print("Please sign up for the Site!")
 
## Example of key argument
def dumb_sentence(name='nawraj',action='ate',item='tuna'):
    print(name,action,item)

dumb_sentence()
dumb_sentence("Sally", "plays", "gently")
dumb_sentence(item ='awesome', action= 'is')

## Example of range
for x in range(10):
    print("Hello nawraj")
 
for x in range(5, 12):
    print(x)
for x in range(10, 40, 5):
    print(x)

## Example of return
def allowed_dating_age(my_age):
    girls_age = my_age/2 + 7
    return girls_age

Age_limit = allowed_dating_age(34)
print("You can date girls", Age_limit, "or older") 
allowed_dating_age(34)

## Example of set
groceries = {'cereal','milk','starcrunch','beer','duct tape','lotion','beer'}
print(groceries)

if 'milk' in groceries:
    print("You already have milk hoss!")
else:
    print("Oh yes you need milk!")
 
## Example of variable scope
#a = 1514
def test1():
    a = 1514
    print(a)

def test2():
    print(a)

test1()
test2()

## Example of dictionary
myDict = {'nawraj': 'lekhak','gayatri': 'Paneru'}
print(myDict)
print(myDict['nawraj'])
print(myDict["nawraj"])

varstr = "this is nawraj " \
         "from cisco systems India " \
         "private limited."
      
      
## Example for prime number
for num in range(2,20):
    if num%2 == 0:
        print ('num is not prime')
        #break
    else:
        print ('num is prime number')

x = range(2,9)
print(x)

## Example of key value
names = {'a': 1, 'b': 2, 'c': 3}
print(names)
x = names.keys()
print(x)
print(names['c'])

## Program for fibonacci
def fib(n):
    a,b = 0,1
    while b < n:
        print(b)
        a,b = b , a+b

fib(3)

or

Certainly! Below is a Python program to generate the Fibonacci sequence up to a specified number of terms:

```python
def fibonacci(n):
    fib_sequence = []
    if n <= 0:
        return fib_sequence
    elif n == 1:
        fib_sequence.append(0)
        return fib_sequence
    else:
        fib_sequence = [0, 1]
        while len(fib_sequence) < n:
            next_num = fib_sequence[-1] + fib_sequence[-2]
            fib_sequence.append(next_num)
        return fib_sequence

# Example usage:
num_terms = 10
fib_sequence = fibonacci(num_terms)
print("Fibonacci sequence with", num_terms, "terms:", fib_sequence)
```

This program defines a function `fibonacci` that takes an integer `n` as input and returns a list containing the Fibonacci sequence up to the `n`th term. The sequence starts with 0 and 1, and each subsequent term is the sum of the two preceding terms.

You can change the value of `num_terms` to generate the Fibonacci sequence with a different number of terms.


## Program to check vowel
letter = 'o'
if letter == 'a' or letter == 'e' or letter == 'i' \
or letter == 'o' or letter == 'u':
    print (letter, 'is a vowel')
else:
    print(letter, 'is not a vowel')
     
### Example of multi-dimensional array
rows = range(1,4)
cols = range(1,3)

cells = [(row,col) for row in rows for col in cols]
for cell in cells:
    print(cell)
 
## decorator example
def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:', func.__name__)
        print('Positional arguments:', args)
        print('keyword arguments:', kwargs)
        result = func(*args, **kwargs)
        print('Result:', result)
        return result
    return new_function

def add_ints(a,b):
    return a + b

add_ints(3,5)

cooler_add_ints = document_it(add_ints)
cooler_add_ints(3,5)
#or
@document_it
def add_ints(a,b):
    return a + b

add_ints(3,5)

## you can have more than one decorator for a function

def square_it(func):
    def new_function(*args, **kwargs):
        result = func(*args, **kwargs)
        return result*result
    return new_function

@document_it
@square_it
def add_ints(a,b):
    return a+b
add_ints(3,5)

###Inheritance
class Car():
    pass

##sub class
class Yugo(Car):
    pass

##create object for each class
give_me_a_car = Car()
give_me_a_yugo = Yugo()

class Car():
    def exclaim(self):
        print('I m a Car')

class Yugo(Car):
    pass

## make one object from each class and call the exclaim method
give_me_a_car = Car()
give_me_a_yugo = Yugo()
give_me_a_car.exclaim()
give_me_a_yugo.exclaim()

##over-ride a method
class Car():
    def exclaim(self):
        print('I am a Car!')

class Yugo(Car):
    def exclaim(self):
        print("I am a Yugo much like car, but more Yugo-ish")

# now make two object from these class
give_me_a_car = Car()
give_me_a_yugo = Yugo()

give_me_a_car.exclaim()
give_me_a_yugo.exclaim()

#super class
class Person():
    def __init__(self, name):
        self.name = name

class EmailPerson(Person):
    def __init__(self, name, email):
        super().__init__(name)
        self.email = email

nawraj = EmailPerson('Nawraj Lekhak','lekhak123@hotmail.com')

print(nawraj.name)
print(nawraj.email)

## regular expression
import re
result = re.match('You', 'Young Frankenstein')
print(result)
#or
source = 'Young Frankenstein'
m = re.match('You', source)
if m:
    print(m.group())  ### print matched value

m = re.match('^You', source)
if m:
    print(m.group()) 

m = re.match('Frank', source)
if m:
    print(m.group())

m = re.search('Frank', source)
if m:
    print(m.group())

m = re.search('.*Frank', source)
if m:
    print(m.group())

m = re.findall('n', source)
print(m)

m = re.findall('n.', source)
print(m)

m = re.findall('n.?', source)
print(m)

m = re.split('n', source)
print(m)

m = re.sub('n', '?', source)
print(m)

## greatest of three
n1 = '902'
n2 = '100'
n3 = '666'

if (n1 > n2) and (n1 > n3):
    print("The greatest number is %s " % n1)
elif (n2 > n1) and (n2 > n3):
    print("The greatest number is %s " % n2)
else:
    print("The greatest number is %s " % n3)

''' odd or even number'''
num = input("Enter a number: ")
mod = num % 2
if mod > 0:
    print (num, "is an odd number")
else:
    print (num, "is an even number")

#### print all elements less than 5
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
num = int(raw_input("Choose a number:"))
new_list = []

for i in a:
    if i < num:
        new_list.append(i)

print(new_list)'''

## current date  and time

import datetime
now = datetime.datetime.now()
print ("Current date and time : ")
print (now.strftime("%Y-%m-%d %H:%M:%S"))

### check whether file exists
import os.path
open('abc.txt', 'w')
print(os.path.isfile('abc.txt'))

###Verify python shell is 32 bit or 64 bit
import struct
print(struct.calcsize("P")*8)

### path and name of file currently executing
import os
print("Current file name: ", os.path.realpath(__file__))

## list all files in dir
from os import listdir
from os.path import isfile, join
files_list = [f for f in listdir('/Users/nawlekha/Desktop/pyATS') if isfile(join('/Users/nawlekha/Desktop/pyATS',f))]
print(files_list)

### python program to access environment variables
import os
print('**********************')
print(os.environ)
print(os.environ['HOME'])
print(os.environ['PATH'])

## get current username
import getpass
print(getpass.getuser())

### convert decimal to hexadecimal
x = 30
print(format(x, '02x'))
x = 4
print(format(x, '02x'))

### program to check valid ip address
import socket
addr = '127.0.0.2561'
try:
    socket.inet_aton(addr)
    print("Valid IP")
except socket.error:
    print("Invalid IP")

## factorial
def fact(x):
    if x == 0:
        return 1
    return x * fact(x - 1)

x = int(input())
print(fact(x))'''

'''
Question:
Define a class which has at least two methods:
getString: to get a string from console input
printString: to print the string in upper case.
Also please include simple test function to test the class methods.
'''

class InputOutString(object):
    def __init__(self):
        self.s = ""

    def getString(self):
        self.s = input()

    def printString(self):
        print(self.s.upper())

strObj = InputOutString()
strObj.getString()
strObj.printString()

##Write a program that accepts a sentence and calculate the number of letters and digits.
s = input()
d = {"DIGITS": 0, "LETTERS": 0}
for c in s:
    if c.isdigit():
        d["DIGITS"]+=1
    elif c.isalpha():
        d["LETTERS"]+=1
    else:
        pass
print("LETTERS", d["LETTERS"])
print("DIGITS", d["DIGITS"])
'''

###Define a class, which have a class parameter and have the same instance parameter.
class Person:
    # Define the class parameter "name"
    name = "Person"

    def __init__(self, name = None):
        # self.name is the instance parameter
        self.name = name

nawraj = Person("nawraj")
print ("%s name is %s" % (Person.name, nawraj.name))

lekhak = Person()
lekhak.name = "lekhak"
print ("%s name is %s" % (Person.name, lekhak.name))

### sum of two numbers
def Sum(n1, n2):
    return n1+n2
print(Sum(1,2))

### Define a class named American and its subclass NewYorker.
class American(object):
    pass
class NewYorker(American):
    pass

anAmerican = American()
aNewYorker = NewYorker()
print(anAmerican)
print(aNewYorker)

###Define a class named Circle which can be constructed by a radius. The Circle class has a method which can compute the area.
class Circle(object):
    def __init__(self,r):
        self.radius = r

    def area(self):
        return self.radius**2*3.14

aCircle = Circle(2)
print(aCircle.area())

#Write a Python program to check that a string contains only a certain set of characters (in this case a-z, A-Z and 0-9).
import re
def check_specific_char(string):
    charRe = re.compile(r'[^a-zA-Z0-9]')
    string = charRe.search(string)
    return not bool(string)

print(check_specific_char("ABCDEFabcdef123456780"))
print(check_specific_char("*&%#!}{"))

#Write a Python program that matches a word containing 'z'.
import re
def text_match(txt):
    pattern = '\w*z. \w*'
    if re.search(pattern, txt):
        return 'match found!'
    else:
        return 'match not found'

print(text_match("the quick brown fox jumps over the lazy dog."))
print(text_match('python exercise'))

'''
## Write a Python program to reverse a string word by word.
class str_reverse:
    def reverse_words(self):
        return ''.join(reversed(s.split()))

print(str_reverse().reverse_words('hello.py'))
'''

or

Sure, here's a Python program to reverse a string word by word:

```python
def reverse_words(sentence):
    # Split the sentence into words
    words = sentence.split()
    # Reverse the order of words
    reversed_words = words[::-1]
    # Join the words back into a sentence
    reversed_sentence = ' '.join(reversed_words)
    return reversed_sentence

# Example usage:
sentence = "Hello World"
reversed_sentence = reverse_words(sentence)
print("Original sentence:", sentence)
print("Reversed sentence:", reversed_sentence)
```

Output:
```
Original sentence: Hello World
Reversed sentence: World Hello
```

In this program:

- The `reverse_words` function takes a string `sentence` as input.
- The `split` method is used to split the sentence into individual words, which are stored in the `words` list.
- The order of words in the `words` list is reversed using slicing with `[::-1]`.
- The `join` method is used to join the reversed words back into a string, with space as the separator.
- The reversed sentence is returned.

You can replace the value of `sentence` with any other string to reverse it word by word.


## strings are immutable sequence of unicode codepoints

''' this is
...a
...multiline
...string.'''

m = 'this string\nspans multiple\n lines.'
print(m)

n = 'this is a \" and a \' in a string.'
print(n)


## manipulate list
b = []
b.append(1.64)
print(b)
b.append(3)
print(b)

def square(x):
    return x*x
print(square(5))

''' __name__ is a special python attribute used to evaluates to "__main__" or the actual
...mddule name depending on how the enclosing module is being used'''

## number of blank line between function should be 2

## shebang #!/usr/bin/ is used to determine which interpreter is used to run program

## Example on variable
varString = "This is a string variable.  It can have " \
            "any combination of letters, numbers, or " \
            "special characters."

varInteger = 32

varLong = 12345

varFloat = 1290.60

varList = [1, 2, 3.5, "Ben", "Alice", "Sam"]

varTuple = (4, 5, 6.5, "Alex", "Barbara", "Amy")

varDictionary = { 'First': 'The first item in the dictionary',
                  'Second' : 'The second item in the dictionary' }

print(varString)
print(varInteger)
print(varLong)
print(varFloat)
print(varList)
print(varTuple)
print(varDictionary)

## input/output
#from __future__ import print_function
userName = input('Please enter your name:' )
finalName = userName + '!'
print('Hello', finalName)

##Functions
def exp(x,y):
    z = x ** y
    print(z)
 
exp(1,2)

def printFib(n):
    a, b = 0,1
    while b < n:
        print(b)
        a, b = b, a+b
     
printFib(4)

def byValExample(x):
    x = "This value is overridden!"
    print(x)
 
byValExample(7)

## Example of OOP
def calcCircumference(radius):
    return math.pi * 2 * radius

class Circle:
    pass

circle1 = Circle()

circle1.radius = 4.2

print(circle1.radius)

circle2 = Circle()
circle2.radius = 3.9
print(circle2.radius)

### Inheritance
class Shape():
    def __init__(self):
        self.color = "Red"
        self.sides = 0

class Square(Shape):
    def __init__(self, w, c):
        Shape.__init__(self)
        self.width = w
        self.color = c

sq1 = Square(5, "Blue")
sq2 = Square(9, "Green")

print("Square Sizes:",sq1.width,"x",sq1.sides,sq1.color,
      ",",sq2.width,"x",sq2.sides,sq2.color)

words = "why sometimes i have believed as many six impossible things before".split()
print(words)

print([len(word) for word in words])

#from math import factorial
#f = [len(str(factorial(x))) for x in range(20)]
#print(f)

## Example of dictionary comprehension
from pprint import pprint as pp
country_to_capital = {'United kingdom': 'London','Brazil': 'Brazilia','Morocco': 'Rabat','Sweden': 'Stockholm'}
pp(country_to_capital.items())
capital_to_country = {capital: country for country, capital in country_to_capital.items()}
pp(capital_to_country)

## filtering predicates
from math import sqrt
def is_prime(x):
    if x < 2:
        return False
    for i in range(2, int(sqrt(x)) + 1):
        if x % i == 0:
            return False
    return True

print([x for x in range(101) if is_prime(x)])

## Generators. It is kind of iterator
def gen123():
    yield 1
    yield 2
    yield 3

g = gen123()
print(next(g))
print(next(g))
print(next(g))

def gen246():
    print("About to yield 2")
    yield 2
    print("About to yield 4")
    yield 4
    print("About to yield 6")
    yield 6
    print("About to return")

h = gen246()
print(next(h))
print(next(h))
print(next(h))


import sys
print(sys.getdefaultencoding())

### word count
from urllib.request import urlopen

with urlopen('http://sixty-north.com/c/t.txt') as story:
    story_words = []
    for line in story:
        line_words = line.decode('utf-8').split()
        for word in line_words:
            story_words.append(word)
print(story_words)

## word count
from urllib.request import urlopen
with urlopen('http://sixty-north.com/c/t.txt') as story:
    story_words = []
    for line in story:
        line_words = line.split()
        for word in line_words:
            story_words.append(word)

print(story_words)

## multiple assignment

target_color_name = first_color_name = 'FireBrick'
id(target_color_name) == id(first_color_name)

## How are the functions help() and dir() different?
These are the two functions that are accessible from the Python Interpreter. These two functions are used for viewing a consolidated dump of built-in functions.

help() - it will display the documentation string. It is used to see the help related to modules, keywords, attributes, etc.

 dir() - will display the defined symbols.
 Eg: >>>dir(str) – will only display the defined symbols.

>>> help(str)

>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>>

## Explain Python's zip() function.?
zip() function- it will take multiple lists say list1, list2, etc and transform them into a single list of tuples by taking the corresponding elements of the lists that are passed as parameters. Eg:

>>> list1 = ['A',
... 'B','C']
>>> list2 = [10,20,30]
>>> list(zip(list1, list2))
[('A', 10), ('B', 20), ('C', 30)]
whenever the given lists are of different lengths, zip stops generating tuples when the first list ends.

## Explain Python's pass by references Vs pass by value. (or) Explain about Python's parameter passing mechanism?
In Python, by default, all the parameters (arguments) are passed “by reference” to the functions. Thus, if you change the value of the parameter within a function, the change is reflected in the calling function.We can even observe the pass “by value” kind of a behavior whenever we pass the arguments to functions that are of type say numbers, strings, tuples. This is because of the immutable nature of them.

## As Everything in Python is an Object, Explain the characteristics of Python's Objects.
As Python’s Objects are instances of classes, they are created at the time of instantiation. Eg: object-name = class-name(arguments)
one or more variables can reference the same object in Python
Every object holds unique id and it can be obtained by using id() method. Eg: id(obj-name) will return unique id of the given object.
every object can be either mutable or immutable based on the type of data they hold.
Whenever an object is not being used in the code, it gets destroyed automatically garbage collected or destroyed
contents of objects can be converted into string representation using a method

## Explain how to overload constructors or methods in Python.
Python’s constructor – _init__ () is a first method of a class. Whenever we try to instantiate a object __init__() is automatically invoked by python to initialize members of an object.

## Which statement of Python is used whenever a statement is required syntactically but the program needs no action?
Pass – is no-operation / action statement in Python
If we want to load a module or open a file, and even if the requested module/file does not exist, we want to continue with other tasks. In such a scenario, use try-except block with pass statement in the except block.
Eg:
 try:import mymodulemyfile = open(“C:\myfile.csv”)except:pass

## Explain the use of with
In python generally “with” statement is used to open a file, process the data present in the file, and also to close the file without calling a close() method. “with” statement makes the exception handling simpler by providing cleanup activities.
General form of with:
with open(“file name”, “mode”) as file-var:
processing statements
note: no need to close the file by calling close() upon file-var.close()

## Explain all the file processing modes supported by Python?
Python allows you to open files in one of the three modes. They are:
read-only mode, write-only mode, read-write mode, and append mode by specifying the flags “r”, “w”, “rw”, “a” respectively.
A text file can be opened in any one of the above said modes by specifying the option “t” along with
“r”, “w”, “rw”, and “a”, so that the preceding modes become “rt”, “wt”, “rwt”, and “at”.A binary file can be opened in any one of the above said modes by specifying the option “b” along with “r”, “w”, “rw”, and “a” so that the preceding modes become “rb”, “wb”, “rwb”, “ab”.

## When does a dictionary is used instead of a list?
Dictionaries – are best suited when the data is labelled, i.e., the data is a record with field names.
lists – are better option to store collections of un-labelled items say all the files and sub directories in a folder.
Generally Search operation on dictionary object is faster than searching a list object.

## What is the use of enumerate() in Python?
Using enumerate() function you can iterate through the sequence and retrieve the index position and its corresponding value at the same time.
>>> for i,v in enumerate([‘Python’,’Java’,’C++’]):
print(i,v)
0 Python
1 Java
2 C++

## How many kinds of sequences are supported by Python? What are they?
Python supports 7 sequence types. They are str, list, tuple, unicode, bytearray, xrange, and buffer. where xrange is deprecated in python 3.5.X.

## Name few methods for matching and searching the occurrences of a pattern in a given text String ?
There are 4 different methods in “re” module to perform pattern matching. They are:
match() – matches the pattern only to the beginning of the String. search() – scan the string and look for a location the pattern matches findall() – finds all the occurrences of match and return them as a list
finditer() – finds all the occurrences of match and return them as an iterator.

## Explain split(), sub(), subn() methods of
To modify the strings, Python’s “re” module is providing 3 methods. They are:
split() – uses a regex pattern to “split” a given string into a list.
sub() – finds all substrings where the regex pattern matches and then replace them with a different string
subn() – it is similar to sub() and also returns the new string along with the no. of
replacements.

## How to display the contents of text file in reverse order?
convert the given file into a list.
 reverse the list by using reversed()
Eg: for line in reversed(list(open(“file-name”,”r”))):
print(line)

## What is TkInter?
TkInter is Python library. It is a toolkit for GUI development. It provides support for various GUI tools or widgets (such as buttons, labels, text boxes, radio buttons, etc) that are used in GUI applications. The common attributes of them include Dimensions, Colors, Fonts, Cursors, etc.

## Is Python object oriented? what is object oriented programming?
Yes. Python is Object Oriented Programming language. OOP is the programming paradigm based on classes and instances of those classes called objects. The features of OOP are:
Encapsulation, Data Abstraction, Inheritance, Polymorphism.

## What is a Class? How do you create it in Python?
A class is a blue print/ template of code /collection of objects that has same set of attributes and behaviour. To create a class use the keyword class followed by class name beginning with an uppercase letter. For example, a person belongs to class called Person class and can have the attributes (say first-name and last-name) and behaviours / methods (say showFullName()). A Person class can be defined as:
class Person():
#method
def inputName(self,fname,lname): self.fname=fname self.lastname=lastname
#method
def showFullName() (self):
print(self.fname+" "+self.lname)person1 = Person() #object instantiation person1.inputName("Ratan","Tata") #calling a method inputName person1. showFullName() #calling a method showFullName()
Note: whenever you define a method inside a class, the first argument to the method must be self (where self – is a pointer to the class instance). self must be passed as an argument to the method, though the method does not take any arguments

## Explain Inheritance in Python with an example.
Inheritance allows One class to gain all the members(say attributes and methods) of another class. Inheritance provides code reusability, makes it easier to create and maintain an application. They are different types of inheritance supported by Python. They are: single, multi-level, hierarchical and multiple inheritance. The class from which we are inheriting is called super-class and the class that is inherited is called a derived / child class.
Single Inheritance – where a derived class acquires the members of a single super class.
multi-level inheritance – a derived class d1 in inherited from base class base1, and d2 is inherited from base2.
hierarchical inheritance – from one base class you can inherit any number of child classes
multiple inheritance – a derived class is inherited from more than one base class.
ex:
class ParentClass:
v1 = "from ParentClass - v1"
v2 = "from ParentClass - v2"class ChildClass(ParentClass):
passc = ChildClass() print(c.v1) print(c.v2)

## How instance variables are different from class variables?
Instance variables: are the variables in an object that have values that are local to that object. Two objects of the same class maintain distinct values for their variables. These variables are accessed with “object-name.instancevariable-name”.

class variables: these are the variables of class. All the objects of the same class will share value of “Class variables. They are accessed with their class name alone as “class- name.classvariable-name”. If you change the value of a class variable in one object, its new value is visible among all other objects of the same class. In the Java world, a variable that is declared as static is a class variable.

## How is Inheritance and Overriding methods are related?
If class A is a sub class of class B, then everything in B is accessible in /by class A. In addition, class A can define methods that are unavailable in B, and also it is able to override methods in B. For Instance, If class B and class A both contain a method called func(), then func() in class B can override func() in class A. Similarly, a method of class A can call another method defined in A that can invoke a method of B that overrides it.

## Differentiate between append() and extend() methods. ?
Both append() and extend() methods are the methods of list. These methods a re used to add the elements at the end of the list.
append(element) – adds the given element at the end of the list which has called this method.
extend(another-list) – adds the elements of another-list at the end of the list which is called the extend method.

## Looking at the below code, write down the final values of A0, A1, ...An.
A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5)))
A1 = range(10)
A2 = sorted([i for i in A1 if i in A0])
A3 = sorted([A0[s] for s in A0])
A4 = [i for i in A1 if i in A3]
A5 = {i:i*i for i in A1}
A6 = [[i,i*i] for i in A1]

Answer
A0 = {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}  # the order may vary
A1 = range(0, 10) # or [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] in python 2
A2 = []
A3 = [1, 2, 3, 4, 5]
A4 = [1, 2, 3, 4, 5]
A5 = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6 = [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]

## What does this code output:
def f(x,l=[]):
    for i in range(x):
        l.append(i*i)
    print(l)

f(2)
f(3,[3,2,1])
f(3)

Answer
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]

Hint
The first function call should be fairly obvious, the loop appends 0 and then 1 to the empty list, l. l is a name for a variable that points to a list stored in memory. The second call starts off by creating a new list in a new block of memory. l then refers to this new list. It then appends 0, 1 and 4 to this new list. So that's great. The third function call is the weird one. It uses the original list stored in the original memory block. That is why it starts off with 0 and 1.

Try this out if you don't understand:

l_mem = []

l = l_mem           # the first call
for i in range(2):
    l.append(i*i)

print(l)            # [0, 1]

l = [3,2,1]         # the second call
for i in range(3):
    l.append(i*i)

print(l)            # [3, 2, 1, 0, 1, 4]

l = l_mem           # the third call
for i in range(3):
    l.append(i*i)

print(l)            # [0, 1, 0, 1, 4]

## What does this stuff mean: *args, **kwargs? And why would we use it?
Answer
Use *args when we aren't sure how many arguments are going to be passed to a function, or if we want to pass a stored list or tuple of arguments to a function. **kwargs is used when we dont know how many keyword arguments will be passed to a function, or it can be used to pass the values of a dictionary as keyword arguments.

Here is a little illustration:

def f(*args,**kwargs): print(args, kwargs)

l = [1,2,3]
t = (4,5,6)
d = {'a':7,'b':8,'c':9}

f()
f(1,2,3)                    # (1, 2, 3) {}
f(1,2,3,"groovy")           # (1, 2, 3, 'groovy') {}
f(a=1,b=2,c=3)              # () {'a': 1, 'c': 3, 'b': 2}
f(a=1,b=2,c=3,zzz="hi")     # () {'a': 1, 'c': 3, 'b': 2, 'zzz': 'hi'}
f(1,2,3,a=1,b=2,c=3)        # (1, 2, 3) {'a': 1, 'c': 3, 'b': 2}

f(*l,**d)                   # (1, 2, 3) {'a': 7, 'c': 9, 'b': 8}
f(*t,**d)                   # (4, 5, 6) {'a': 7, 'c': 9, 'b': 8}
f(1,2,*t)                   # (1, 2, 4, 5, 6) {}
f(q="winning",**d)          # () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f(1,2,*t,q="winning",**d)   # (1, 2, 4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}

def f2(arg1,arg2,*args,**kwargs): print(arg1,arg2, args, kwargs)

f2(1,2,3)                       # 1 2 (3,) {}
f2(1,2,3,"groovy")              # 1 2 (3, 'groovy') {}
f2(arg1=1,arg2=2,c=3)           # 1 2 () {'c': 3}
f2(arg1=1,arg2=2,c=3,zzz="hi")  # 1 2 () {'c': 3, 'zzz': 'hi'}
f2(1,2,3,a=1,b=2,c=3)           # 1 2 (3,) {'a': 1, 'c': 3, 'b': 2}

f2(*l,**d)                   # 1 2 (3,) {'a': 7, 'c': 9, 'b': 8}
f2(*t,**d)                   # 4 5 (6,) {'a': 7, 'c': 9, 'b': 8}
f2(1,2,*t)                   # 1 2 (4, 5, 6) {}
f2(1,1,q="winning",**d)      # 1 1 () {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}
f2(1,2,*t,q="winning",**d)   # 1 2 (4, 5, 6) {'a': 7, 'q': 'winning', 'c': 9, 'b': 8}

## What do these mean to you: @classmethod, @staticmethod, @property?
These are decorators. A decorator is a special kind of function that either takes a function and returns a function, or takes a class and returns a class. The @ symbol is just syntactic sugar that allows you to decorate something in a way that's easy to read.

@my_decorator
def my_func(stuff):
    do_things

Is equivalent to

def my_func(stuff):
    do_things

my_func = my_decorator(my_func)

## Consider the following code, what will it output?
class A(object):
    def go(self):
        print("go A go!")
    def stop(self):
        print("stop A stop!")
    def pause(self):
        raise Exception("Not Implemented")

class B(A):
    def go(self):
        super(B, self).go()
        print("go B go!")

class C(A):
    def go(self):
        super(C, self).go()
        print("go C go!")
    def stop(self):
        super(C, self).stop()
        print("stop C stop!")

class D(B,C):
    def go(self):
        super(D, self).go()
        print("go D go!")
    def stop(self):
        super(D, self).stop()
        print("stop D stop!")
    def pause(self):
        print("wait D wait!")

class E(B,C): pass

a = A()
b = B()
c = C()
d = D()
e = E()

# specify output from here onwards

a.go()
b.go()
c.go()
d.go()
e.go()

a.stop()
b.stop()
c.stop()
d.stop()
e.stop()

a.pause()
b.pause()
c.pause()
d.pause()
e.pause()

Answer

The output is specified in the comments in the segment below:

a.go()
# go A go!

b.go()
# go A go!
# go B go!

c.go()
# go A go!
# go C go!

d.go()
# go A go!
# go C go!
# go B go!
# go D go!

e.go()
# go A go!
# go C go!
# go B go!

a.stop()
# stop A stop!

b.stop()
# stop A stop!

c.stop()
# stop A stop!
# stop C stop!

d.stop()
# stop A stop!
# stop C stop!
# stop D stop!

e.stop()
# stop A stop!

a.pause()
# ... Exception: Not Implemented

b.pause()
# ... Exception: Not Implemented

c.pause()
# ... Exception: Not Implemented

d.pause()
# wait D wait!

e.pause()
# ...Exception: Not Implemented

## What is lambda in Python?
It is a single expression anonymous function often used as inline function.

## In Python what is slicing?
A mechanism to select a range of items from sequence types like list, tuple, strings etc. is known as slicing.

## What are generators in Python?
The way of implementing iterators are known as generators.  It is a normal function except that it yields expression in the function.

## What is docstring in Python?
A Python documentation string is known as docstring, it is a way of documenting Python functions, modules and classes.

## How can you copy an object in Python?
To copy an object in Python, you can try copy.copy () or copy.deepcopy() for the general case. You cannot copy all objects but most of them.

## What is the difference between Xrange and range?
Xrange returns the xrange object while range returns the list, and uses the same memory and no matter what the range size is.

## What will be the output of the code below? 
def extendList(val, list=[]):
list.append(val)
return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print ("list1 = %s" % list1)
print ("list2 = %s" % list2)
print ("list3 = %s" % list3)

'''
Output:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
'''

## What will be the output of the code below? 

def multipliers():
  return [lambda x : i * x for i in range(4)]

print ([m(2) for m in multipliers()])

'''
The output of the above code will be [6, 6, 6, 6] (not [0, 2, 4, 6]).
'''

## What will be the output of the code below? 

class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print (Parent.x, Child1.x, Child2.x)
Child1.x = 2
print (Parent.x, Child1.x, Child2.x)
Parent.x = 3
print (Parent.x, Child1.x, Child2.x)

'''
The output of the above code will be:

1 1 1
1 2 1
3 2 3
'''

## What will be the output of the code below in Python
def div1(x,y):
    print ("%s/%s = %s" % (x, y, x/y))

def div2(x,y):
    print ("%s//%s = %s" % (x, y, x//y))

div1(5,2)
div1(5.,2)
div2(5,2)
div2(5.,2.)

'''
5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
'''

## What will be the output of the code below?

list = ['a', 'b', 'c', 'd', 'e']
print (list[10:])

'''
The above code will output []
'''

## What will be the output of lines ?
list = [ [ ] ] * 5
print(list)
list[0].append(10)
print(list)
list[1].append(20)
print(list)
list.append(30)
print(list)

'''
The output will be as follows:

[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]
'''

'''
Given a list of N numbers, use a single list comprehension to produce a new list that only contains those values that are:
(a) even numbers, and
(b) from elements in the original list that had even indices
'''

list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ]
print([x for x in list[::2] if x%2 == 0])

'''
Output is : [10, 18, 78]
'''

## Name five modules that are included in python by default?
datetime           (used to manipulate date and time)
re                         (regular expressions)
urllib, urllib2  (handles many HTTP things)
string                  (a collection of different groups of strings for example all lower_case letters etc)
itertools            (permutations, combinations and other useful iterables)
ctypes                (from python docs: create and manipulate C data types in Python)
email                  (from python docs: A package for parsing, handling, and generating email messages)

## What is a docstring?
docstring is the documentation string for a function. It can be accessed by

function_name.__doc__

it is declared as:
def function_name():
"""your docstring"""
Writing documentation for your progams is a good habit and makes the code more understandable and reusable.

What is list comprehension?
Creating a list by doing some operation over data that can be accessed using an iterator. For eg:
>>>[ord(i) for i in string.ascii_uppercase]
     [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
 >>>

 What would the following code yield?
word = 'abcdefghij'
print word[:3] + word[3:]
Ans: ‘abcdefghij’ will be printed.
This is called string slicing. Since here the indices of the two slices are colliding, the string slices are ‘abc’ and ‘defghij’. The ‘+’ operator on strings concatenates them. Thus, the two slices formed are concatenated to give the answer ‘abcdefghij’.

Optimize these statements as a python programmer.
word = 'word'
print word.__len__()
Ans:

word = 'word'
print(len(word))

Write a program to print all the contents of a file
try:
    with open('sample.py','r') as f:
        print (f.read())
except IOError:
    print ("no such file exists")

Print the length of each line in the file ‘file.txt’ not including any whitespaces at the end of the lines.
with open("sample.py", "r") as f1:
  print(len(f1.readline().rstrip()))

rstrip() is an inbuilt function which strips the string from the right end of spaces or tabs (whitespace characters).

Print the sum of digits of numbers starting from 1 to 100 (inclusive of both)
print sum(range(1,101))
range() returns a list to the sum function containing all the numbers from 1 to 100. Please see that the range function does not include the end given (101 here).

Create a new list that converts the following list of number strings to a list of numbers.
>>> num_strings = ['1','21','53','84','50','66','7','38','9']
>>> [int(i) for i in num_strings]
[1, 21, 53, 84, 50, 66, 7, 38, 9]

Create two new lists one with odd numbers and other with even numbers
num_strings = [1,21,53,84,50,66,7,38,9]
>>> even = [i for i in num_strings if i%2==0]
>>> print(even)
[84, 50, 66, 38]
>>> odd = [i for i in num_strings if i%2==1]
>>> print(odd)
[1, 21, 53, 7, 9]

The following code is supposed to remove numbers less than 5 from list n, but there is a bug. Fix the bug.
n = [1,2,5,10,3,100,9,24]
for e in n:
  if e<5: p="">    n.remove(e)
  print n

## after e is removed, the index position gets disturbed. Instead it should be:
a=[]
for e in n:
  if e >= 5:
    a.append(e)
n = a

OR again a list comprehension
print([i for i in n if i >= 5])


What will be the output of the following
def func(x,*y,**z):
....    print z

func(1,2,3)

Here the output is :

{}  #Empty Dictionay

x is a normal value, so it takes 1..
y is a list of numbers, so it takes 2,3..
z wants named parameters, so it can not take any value here.
Thus the given answer.

Write a program to swap two numbers.
a = 5
b = 9
>>> a = 5
>>> b = 4
>>> a,b = b,a
>>> print(a)
4
>>> print(b)
5

What will be the output of the following code
class C(object):
....    def__init__(self):
....        self.x =1

c=C()
print c.x
print c.x
print c.x
print c.x
Ans.

All the outputs will be 1, since the value of the the object’s attribute(x) is never changed.

1
1
1
1

x is now a part of the public members of the class C.
Thus it can be accessed directly

What all options will work?
a.
n = 1
print n++   ## no such operator in python (++)

b.
n = 1
print ++n   ## no such operator in python (++)

c.
n = 1
print n += 1  ## will work

d.
int n = 1
print n = n+1 ##will not work as assignment can not be done in print command like this

e.
n =1
n = n+1      ## will work

Remove the whitespaces from the string.
s = ‘aaa bbb ccc ddd eee’
''.join(s.split())

What does the below mean?
s = a + ‘[‘ + b + ‘:’ + c + ‘]’
seems like a string is being concatenated. Nothing much can be said without knowing types of variables a, b, c. Also, if all of the a, b, c are not of type string, TypeError would be raised. This is because of the string constants (‘[‘ , ‘]’) used in the statement.

Sunday, March 12, 2017

Python Reference

So, what is Python?
Simply put, Python is a programming language. It was initially developed by Guido Van Rossom in the late 1980's in the Netherlands.  Python is developed as an open source project and is free to download and use as you wish. On a technical level, Python is a strongly typed language in the sense that every object in the language has a definite type, and there's generally no way to circumvent that type. At the same time, Python is dynamically typed meaning that there's no type checking of your code prior to running it. This is, in contrast, to statically typed languages like C++ or Java where a compiler does a lot of type checking for you rejecting programs, which misuse objects. Ultimately, the best description of the Python type system is that it uses duck typing where an object's suitability for a context is only determined at runtime.  Python is a general-purpose programming language. It's not intended for use in any particular domain or environment, but instead can be fruitfully used in a wide variety of tasks. There are of course some areas where it's less suitable than others, for example, in extremely time sensitive or memory constrained environments, but for the most part Python is as flexible and adaptable as many modern languages and more so than most. Python is an interpreted language. This is a bit of a myth statement technically because Python is normally compiled into a form of bytecode before it's executed. However, this compilation happens invisibly, and the experience of using Python is one of immediately executing code without a noticeable compilation phase. This lack of an interruption between editing and running is one of the great joys of working with Python. The syntax of Python is designed to be clear, readable, and expressive. Unlike many popular languages, Python uses whitespace to delimit code blocks and in the process does away with reams of unnecessary parentheses while enforcing a universal layout. There are multiple implementations of the Python language. The original, and still by far the most common implementation, is written in C. This version is commonly referred to as C Python. When someone talks about running Python, it's normally safe to assume that they are talking about C Python, and this is the implementation that we'll be using for this course. Other implementations of Python include Jython, which is written to target the Java virtual machine; Iron Python, which targets the .NET runtime; and pypy, which is written in a specialized subset of Python called RPython. There are two important versions of the Python language in common use right now, Python 2 and Python 3. Python 2 is older and better established than Python 3, but Python 3 addresses some known shortcomings in the older version. Python 3 is the definite future of Python, and you should use it if at all possible.

Python Overview
Beyond being a programming language, Python comes with a powerful and broad standard library. Part of the Python philosophy is batteries included the meaning that you can use Python for many complex real-world tasks out-of-the-box with no need to install third-party packages. This is not only extremely convenient, but it means that it's easier to get started using Python using interesting engaging examples, something we aim for in this course. Another great effect of the batteries included approach is that it means that many scripts, even non- trivial ones, can be run immediately on any Python installation. This removes the common annoying barrier to installing software that you face with some languages. The standard library has a generally high level of good documentation. APIs are well documented, and the modules often have good narrative descriptions with quick start guides, best practice information, and so forth. The standard library documentation is always available online at python.org, and you can also install it locally if you need to.

The Read-Eval-Print-Loop or REPL
This Python command line environment is a Read-Eval-Print-Loop. Python will read whatever input we type in, evaluate it, print the result, and then loop back to the beginning. You'll often hear it referred to as simply the REPL. When started, the REPL will print some information about the version of Python you're running, and then it will give you a triple arrow prompt. This prompt tells you that Python is waiting for you to type something. Within an interactive Python session, you can enter fragments of Python programs and see instant results. Let's start with some simple arithmetic. 2 + 2 is 4. As you can see, Python reads that input, evaluates it, prints the result, and loops around to do the same again. 6 * 7 is 42. We can assign to variables in the REPL, x = 5, and print their content simply by typing their name. We can also refer to variables and expressions such as 3 * x. As an aside, a print is one of the biggest differences between Python 2 and Python 3. In Python 3 the parentheses are required whereas in Python 2 they were not. This is because in Python 3 print is a function call. More on functions later. At this point, we should show you how to exit the REPL. We do this by sending the end of file control character to Python, although unfortunately, the means of sending this character varies across platforms. If you're on Windows, press Control+Z to exit. If you're on Mac or Linux, press Control+D to exit. If you regularly switch between platforms and you accidentally press Control+Z on a Unix-like system, you'll inadvertently suspend the Python interpreter and return to your operating system's shell. To reactivate Python making it a foreground process again, simply run the fg command, and press Enter a couple of times to get the triple arrow Python prompt back.

Significant Whitespace in Python
Start your Python 3 interpreter using the Python or Python 3 command for Windows or Unix-like systems respectively. The control flow structures of Python such as for loops, while loops, and if statements are all introduced by statements which are terminated by a colon indicating that the body of the construct is to follow. For example, for loops require a body. So, if you enter for i in range(5), Python will change the prompt to three dots to request you provide the body. One distinctive and sometimes controversial aspect of Python is that leading whitespace is syntactically significant. What this means is that Python uses indentation levels rather than the braces used by other languages to demarcate code blocks. By convention, contemporary Python code is indented by four spaces for each level, so we provide those four spaces and a statement to form the body of our loop, x = i * 10. Our loop body will contain the second statement. So, after pressing Return, at the next three dot prompt we enter another four spaces followed by a call to the built-in print function. To terminate our block, we must enter a blank line into the REPL. With the block complete, Python executes the pending code printing out the multiples of 10 less than 50. Looking at a screen full of Python code, we can see how the indentation clearly matches, and in fact must match the structure of the program. Even if we replace the code by gray lines, the structure of the program is clear. Each statement terminates by a colon, starts a new line, and introduces an additional level of indentation, which continues until a dedent restores the indentation to a previous level. Each level of indent is typically four spaces, although we'll cover the rules in more detail in a moment. Python's approach to significant whitespace has three great advantages. First, it forces developers to use a single level of indentation in a code block. This is generally considered good practice in any language because it makes code much more readable. Second, code with a significant whitespace doesn't need to be cluttered with unnecessary braces, and you never need to have a code standard debate about where the braces should go. All code blocks in Python code are easily identifiable, and everyone writes them the same way. Third, significant whitespace requires that a consistent interpretation must be given to the structure of the code by the author, the Python runtime system, and future maintainers who need to read the code, so you can never have code that contains a block from Python's point of view, but which doesn't look like it from a cursory human perspective. The rules for Python indentation can seem complex, but are straightforward in practice. The whitespace you use can either be spaces or tabs. The general consensus is that spaces are preferable to tabs, and four spaces has become standard in the Python community. One essential rule is never to mix spaces and tabs. The Python interpreter will complain, and your colleagues will hunt you down. You are allowed to use different amounts of indentation at different times if you wish. The essential rule is that consecutive lines of code at the same indentation level are considered to be part of the same code block. There are some exceptions to these rules, but they almost always have to do with improving code readability in other ways, for example, by breaking up necessarily long statements over multiple lines.

Python Culture and the Zen of Python
Many programming languages are at the center of a cultural movement. They have their own communities, values, practices, and philosophy, and Python is no exception. The development of the Python language itself is managed through a series of documents called Python Enhancement Proposals or PEPs. One of the PEPs called PEP 8 explains how you should format your code, and we follow its guidelines throughout this course. It is PEP 8 which recommends we use four spaces for indentation in new Python code. Another of these PEPs called PEP 20 is called The Zen of Python. It refers to 20 aphorisms describing the guiding principles of Python, only 19 of which have been written down. Conveniently, The Zen of Python is never further away than the nearest Python interpreter as it can always be accessed from the REPL by typing import this.

Importing From the Python Standard Library
As mentioned earlier, Python comes with an extensive Standard Library, an aspect of Python often referred to as Batteries Included. The Standard Library is structured as modules, a topic we'll discuss in depth later in the course. What's important at this stage is to know that you gain access to Standard Library modules using the import keyword. The basic form of importing a module is simply the import keyword followed by a space and the name of the module. For example, let's see how we can use the Standard Library's math module to compute square roots. At the triple arrow prompt, we type import math. Since import is the statement which doesn't return a value, Python doesn't print anything if the import succeeds and we immediately return to the prompt. We can access the contents of the imported module by using the name of the module followed by a dot followed by the name of the attribute in the module that you need. Like many object-oriented languages, the dot operator is used to drill down into object structures. Being expert Pythonistas, we have inside knowledge that the math module contains a function called square root. Let's try to use it. But how can we find out what other functions are available in the math module? The REPL has a special function, help, which can retrieve any embedded documentation from objects for which it has been provided such as Standard Library modules. To get help, type simply help. We'll leave you to explore the first form of interactive help in your own

Scalar Types: int, float, None and boolean
Python comes with a number of built-in data types. These include primitive scalar types like integers, as well as collection types like dictionaries. These built-in types are powerful enough to be used alone for many programming needs, and they can be used as building blocks for creating more complex data types. In this section we'll cover the basic scalar built-in types int, float, None, and bool. We'll provide basic information about these now showing their literal forms and how to create them. We've already seen quite a lot of Python integers in action. Python integers are signed and have for all practical purposes unlimited precision. Integer literals in Python are specified in decimal, but may also be specified in binary with a 0b prefix, up top with a 0o prefix, or hexadecimal with a 0x prefix. We can also construct integers by a call to the int constructor, which can convert from other numeric types such as floats to integers. Note that rounding is always towards 0. We can also convert strings to integers. To convert from base 3, use int and then 10000 as a string comma 3. Floating point numbers are supported in Python by the float type. Python floats are implemented as IEEE-754 double precision floating point numbers with 53 bits of binary precision. This is equivalent to between 15 and 16 significant digits in decimal. Any literal number containing a decimal point or a letter E is interpreted by Python as a float. Scientific notation can be used. So, for large numbers such as the approximate speed of light in meters per second 3 times 10 to the 8, we can write 3e8. And for small numbers like Planck's constant 1.616 times 10 to the -35, we can enter 1.616e-35. Notice how Python automatically switches the display representation to the most readable form. As for integers, we can convert to floats from other numeric or string types using the float constructor from an int and from a string. This is also how we create the special floating- point values nan or not a number and also positive and negative infinity. The result of any calculation involving int and float is promoted to a float. Python has a special null value called None with a capital N. None is frequently used to represent the absence of a value. The Python REPL never prints None results, so typing None into the REPL has no effect. None can be bound to a variable name just like any other object, and we can test whether an object is None by using Python's is operator. We can see here that the response is True, which brings us conveniently onto the bool type. The bool type represents logical states and plays an important role in several of Python's control flow structures as we'll see shortly. As you would expect, there are two bool values, True and False, both with initial capitals, and also a bool constructor, which can be used to convert from other types to bool. Let's look at how it works. For integers, 0 is considered false, and all other values truthy. (Typing) We see the same behavior with floats where only 0 is considered false. (Typing) When converting from collections such as strings or lists, only empty collections are treated as false.

Relational Operators

Bool values are commonly produced by Python's relational operators, which can be used for comparing objects. The relational operators are sometimes called the comparison operators. These include value equality and inequality, less-than, greater-than, less-than or equal to, and greater- than or equal to. Two of the most widely used relational operators are Python's equality and inequality tests, which actually test for equivalence or inequivalence of values. That is two objects are equivalent if one could be used in place of the other. We'll learn more about the notion of object equivalence later in the course. For now, we'll simply compare integers. Let's start by assigning or binding a value to a variable g. We test for equality with a double equals operator or for inequality using the not equals operator. We can also compare the order of quantity using the so-called rich comparison operators less-than, greater-than, less-than or equal to, and greater than or equal to.

Conditional Statements
Now we've examined some basic built-in types. We'll look at two important control flow structures, which depend on conversions to the bool type, while loops, but first if statements. Conditional statements allow us to branch execution based on the value of an expression. The form of the statement is the if keyword followed by an expression terminated by a colon to introduce a new block. The expression is converted to bool as if by the bool constructor. Let's try this at the REPL. Remembering to indent four spaces within the block, we add some code to be executed if the condition is True followed by a blank line to terminate the block at which point the block will execute because self- evidently the condition is true. Conversely, if the condition is False, the code in the block does not execute. Because the expression used with the if statement will be converted to bool just as if the bool constructor had been used, this form (Typing) is exactly equivalent to this form. (Typing) Thanks to this useful shorthand, explicit conversion to bool using the bool constructor is rarely used in Python. The if statement supports an optional else clause, which goes in a block introduced by the else keyword followed by a colon, which is indented to the same level as the if keyword. To start the else block, in this case, we just omit the indentation after the three dots. (Typing) For multiple conditions, you might be tempted to do something like this, nesting if statements. Whenever you find yourself with an else block containing a nested if statement like this, you should consider instead using Python's elif keyword, which is a combined else/if.

Summary
Let's summarize what we've seen. We started by obtaining and installing Python 3 for Windows, Ubuntu Linux, and Mac OS X. We then looked at the Read-Eval-Print-Loop or REPL, and how it allows us to interactively explore Python code. We learned some simple arithmetic operators with plus, minus, multiply, divide, modulus, and the integer division operator with a double slash. We discovered we could give objects names with the assignment operator using the equals symbol. We learned how to print objects, and we showed you how to exit the REPL, which is different on Windows with Control+Z or Linux and Mac with Control+D. We showed how Python uses significant indentation of code to demarcate code blocks. Each indent level is usually four spaces. And we told you about Python Enhancement Proposals, the documents which govern the evolution of the Python language. In particular, we briefly looked at PEP 8, which is the Python Style Guide, which we follow in this course, and PEP 20, The Zen of Python, which gives useful advice on writing Pythonic code. We looked at importing Python's Standard Library modules using the import statement. Import has three forms: Import module, from module import function, and from module import function as alias. We used all three of these forms during this course module. We showed how to find and browse help(), particularly useful for discovering the Standard Library. We looked at the four built-in scalar types int, float, None, and bool and showed how to convert between these types and use their literal forms. We looked at the six relational operators equality, inequality, less-than, greater-than, less-than or equal to, and greater than or equal to. These are used for equivalence testing and ordering. We demonstrated structuring conditional code with if, elif, else structures. We shared iterating with while loops and how to interrupt execution of infinite loops using Control+C, which generates a keyboard interrupt exception. We gave an example of how to break out of a loop using the break statement, which breaks out of the innermost loop onto the first statement immediately following the loop, and along the way we looked at the augmented assignment operators for modifying objects in place such as counter variables. We also looked at requesting text from the user at the console with the built-in input() function. Next time here on Python Fundamentals we'll continue our exploration of Python's built-in types and control flow structures by looking at strings, lists, dictionaries, and for-loops. We'll even be using Python to fetch some data from the web for processing.

Strings and Collections Summary
Python has support for universal newlines, so no matter what platform you're using, it's sufficient to use a single slash N character safe in the knowledge that it will be appropriately translated to and from the native newline during I/O. Escape sequences provide an alternative means of incorporating newlines and other control characters into literal strings. The backslashes used for escaping can be a hindrance for Windows file system paths or regular expressions, so raw strings with an R prefix can be used to suppress the escaping mechanism.
Other types such as integers can be converted to strings using the str() constructor. Individual characters returned as one character strings can be retrieved using square brackets with integer zero-based indices. Strings support a rich variety of operations such as splitting through their methods. In Python 3 literal strings can contain Unicode characters directly in the source. The bytes type has many of the capabilities of strings but is a sequence of bytes rather than a sequence of Unicode codepoints. Bytes literals are prefixed with a lowercase B. To convert between string and bytes instances, we use the encode() method of str and the decode() method of bytes in both cases passing the encoding, which we must know in advance. Lists are mutable, heterogeneous sequences of objects. List literals are delimited by square brackets, and the items are separated by commas. As with strings, individual elements can be retrieved by indexing into a list with square brackets. In contrast to strings, individual list elements can be replaced by assigning to the indexed item. Lists can be grown by appending to them and can be constructed from other sequences using the list() constructor. Dictionaries associate keys with values. Literal dictionaries are delimited by curly braces. The key value pairs are separated from each other by commas, and each key is associated with its corresponding value with a colon. For-loops take items one-by-one from an iterable object such as a list and bind the name to the current item. For-loops correspond to what are called for-each loops in other languages.

Modularity - Summary
  • python code is placed in *.py files called "modules"
  • Modules can be executed directly with 
    • python module_name.py
  • Brought into the REPL or other modules with 
    • import module_name
  • Named functions defined with the def keyword
    •  def function_name(arg1, argn):
  • Return from functions using return keyword with optional parameter
  • Omitted return parameter or implicit return at end returns None
  • Use __name__ to determine how the module is being used
  • if __name__ == "__main__" the module is being executed
  • Mode code is executed excatly once, on first import
  • def is a statement which binds a function definition to a name
  • Command line arguments are accessible through sys.argv
  • The script filename is in sys.argv[0]
  • Docstrings are a standalone literal string as the first statement of a function or module
  • Docstrings are delimited by triple quotes
  • Docstrings provide help()
  • Module docstrings should precede other statements
  • Comments begin with # and run to the end of the line
  • A special comment on the first line beginning #! controls module execution by the program loader.
Objects Summary
  • Think for named references to objects rather than variables
    • Assignment attached a name to an object
    • Assigning from one reference to another puts two name tags on the same object
  • The garbage collector reclaims unreachable objects
  • id() returns a unique and constant identifier
    • rarely used in production
  • The is operator determines equality of identify
  • Test for equivalence using ==
  • Function arguments are passed by object reference
    • function can modify mutable arguments
  • Reference is lost if a formal function argument is rebound
    • to change a mutable argument, replace its contents
  • return also passes by object reference
  • Function arguments can be specified with defaults
  • Default argument expressions evaluated once, when def is executed.
  • Python uses dynamic typing
    • we don't specify types in advance
  • Python uses strong typing
    • types are not coerced to match
  • Names are looked up in four nested scopes
    • LEGB rule: Local, Enclosing, Global, and Built-ins
  • Global references can be read from local scope
  • Use global to assign to global references from a local scope
  • Everything in Python is an object
    • This includes modules and functions
    • They can be treated just like other objects.
  • import and def result in binding to named references
  • type can be used to determine the type of the object
  • dir() can be used to introspect an object and gets its attributes
  • The name of a function or module object can be accessed through its __name__ attribute
  • The docstring for a function or module object can be accessed through its __doc__ attribute.
  • Use len() to measure the length of string
  • You can multiply a string by an integer
    • Produces a new string with multiple copies of the operand
    • This is called the "repetition" operation
Collection Summary
  • Tuples are immutable sequence types
    • literal syntax: optional parentheses around a comma-separated list
    • Single element tuples must use trailing comma
    • Tuple unpacking - return values and idomatic swap
  • Strings are immutable sequence types of Unicode codepoints
    • string concatenation is most efficiently performed with join() on an empty separator
    • The partition() method is a useful and elegant string parsing tool
    • The format() method provides a powerful way of replacing placeholders with values.
  • Ranges represent integer sequences with regular intervals
    • Ranges are arithmetic progression
    • The enumerate() function is often a superior alternative to range()
  • Lists are heterogeneous mutable sequence types
    • Negative indexes work backwards from the end.
    • Slicing allows us to copy all or part of the list.
    • The full slice is a common idiom for copying lists, although the copy() method and list() constructor are less obscure.
    • List repetition is shallow.
    • Heterogeneous: "Heterogeneous" means that a list can contain elements of different data types. For example, a list can contain integers, strings, floats, or even other lists.
  • Dictionaries map immutable keys to mutable values
    • Iteration and membership testing is done with respect to the keys.
    • Order is arbitrary
    • The keys(), values() and items() methods provide views onto different aspects of a  dictionary, allowing convenient iteration.
  • Sets store and unordered collection of unique elements
    • sets support powerful and expressive set algebra operations and predicates.
    • Unordered: "Unordered" means that the elements in a set are not stored in any particular order. Unlike lists or tuples, where elements are stored in a specific sequence, sets do not guarantee any specific order for their elements. When you iterate over a set or print it out, the order in which the elements appear may vary.
  • Protocols such as iterable, sequence and container characterise the collections
Exception handling Summary : 
  • Raising an exception interrupts normal program flow and transfers control to an exception handler.
  • Exception handlers defined using the try...except construct
  • try blocks define a context for detecting exceptions.
  • Corresponding except blocks handle specific exception types.
  • Python uses exceptions pervasively.
    • Many built-in language features depend on them.
    • The statement "Python uses exceptions pervasively" means that exceptions are an integral part of Python's programming paradigm, and they are used extensively throughout the language and its standard libraries
  • except block can capture an exception, which are often of a standard type.
  • Programmer errors should not normally be handled.
  • Exceptional conditions can be signalled using raise.
  • raise without an argument re-raises the current exception.
  • Generally, do not check for TypeErrors.
  • Exception objects can be converted to strings using str().
  • Use the try...finally construct to perform cleanup actions.
    • may be in conjunction with except blocks.
  • Output of print() can be redirected using the optional file argument.
  • Use and and or  for combining boolean expressions.
  • Return codes are too easily ignored.
Comprehensions, Generators & Iterables Summary
Comprehensions
  • Comprehensions are a concise syntax for describing lists, sets and dictionaries.
  • Iterables are objects over which we can iterate item by item.
  • We retrieve an iterator from an iterable object using built-in iter() function.
  • Iterators produce items one-by-one from the underlying iterable series each time they are passed to the built-in next() function.
Generators
  • Generator functions allow us to describe series using imperative code.
  • Imperative code in Python refers to a programming paradigm where the focus is on describing the steps or procedures required to achieve a certain result. In imperative programming, the code consists of a sequence of statements that explicitly specify how the program should perform a task.
  • Generator functions contain at least one use of the yield keyword.
  • Generators are iterators. When advanced with next() the generator starts or resumes execution up to and including the next yield.
  • Each call to a generator function creates a new generator object
  • Generators can maintain explicit state in local variables between iterations.
  • Generator expressions have a similar syntactic form to list comprehensions and allow for a more declarative and concise way of creating generator objects.
Classes Summary
  • All types in Python have a 'class'
  • Classes define the structure and behaviour of object
  • Class is determined when object is created
    • normally fixed for a lifetime
  • Classes are the key support for OOP in Python.
  • Classes defined using the class keyword followed by CamelCase name
  • Class instances created by calling the class as if it were a function
  • Instance methods are functions defined inside a class
    • should accept an object instance called self as the first parameter
  • Methods are called using instance.method()
  • The optional __init__() method initialized new instances
    • if present, the constructor calls __init__()
    • __init__() is not the constructor
  • Arguments passed to the constructor are forwarded to the initializer
  • Instance attributes are created simply by assigning to them
  • Implementation details are denoted by a leading underscore
  • Class invariants should be established in the initializer
  • Methods can have docstrings, just like regular functions
  • Classes can have docstrings
  • Even within an object method calls must be preceded with self
  • You can have as many classes and functions in a module
  • Polymorphism in Python is achieved through duck typing
  • In Python, polymorphism is achieved through duck typing. Duck typing is a programming concept that focuses on an object's behavior rather than its type. The term "duck typing" comes from the saying, "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck."

    In Python, when an object is passed to a function or method, the interpreter does not check the object's type explicitly. Instead, it checks whether the object supports the required behavior or methods. If the object provides the required methods or attributes, it can be used in a polymorphic manner, regardless of its actual type.

  • Polymorphism in Python does not use shared base classes or interfaces
  • All methods are inherited, including special methods like the initializer
Files and resource management Summary
  • Files are opened using the built-in open() function which accepts a file mode to control read/write/append behaviour and whether the file is to be treated as raw binary or encoded text data.
  • For text data you should specify a text encoding.
  • Text files deal with string objects and perform universal newline translation and string encoding.
  • Binary files deal with bytes objects with no newline translation or encoding.
  • When writing files, it's our responsibility to provide newline characters for a line breaks
  • Files should always be closed after use.
  • Files provide various line-oriented methods for reading, and are also iterators which yield line by line.
  • Files are context managers and the with-statement can be used with context managers to ensure that clean up operations, such as closing files are performed.
  • Context managers are used to set up and tear down temporary contexts, establish and resolve custom settings, and acquire and release resources. The open() function for opening files is one of the most familiar examples of a context manager.
Maintainable code summary
  • unit test is a framework for developing reliable automated tests
  • You define test cases by subclassing from unit test.Testcase
  • unittest.main() is useful for running all the tests in a module.
  • setUp() and tearDown() run code before and after each test method.
  • Test methods are defined by creating method name start with test_
  • TestCase.assert.. methods make a test method fail when the right conditions aren't met.
  • Use TestCase.assertRaises() in a with-statement to check that the right exceptions are thrown in a test
  • Python's standard debugger is called PDB
  • PDB is a standard command line debugger
  • pdb.set_trace() can be used to stop program execution and enter the debugger.
  • Your REPL's prompt will change to Pdb when you are in the debugger.
  • You can access PDB's built-in help system by typing help
  • Use "python -m pdb

What is scope resolution?
In Python, a scope defines the region of code where an object remains valid and accessible. Every object in Python operates within its designated scope. Namespaces are used to uniquely identify objects within a program, and each namespace is associated with a specific scope where objects can be used without any prefix. The scope of a variable determines its accessibility and lifespan.

Let’s explore the different scopes created during code execution:

Local scope: This refers to the objects that are defined within the current function and are accessible only within that function.

Global scope: Objects in the global scope are available throughout the execution of the code. 
Module-level scope: This scope encompasses global objects that are associated with the current module in the program. These objects are accessible within the module.
Outermost scope: This refers to all the built-in names that can be called from anywhere in the program.

How does break, continue, and pass work?
The following statements assist in altering the course of execution from the regular flow, which categorizes them as loop control statements.

Python break: This statement aids in discontinuing the loop or the statement and transferring control to the subsequent statement.

Python continue: This statement enforces the execution of the subsequent iteration when a particular condition is met, instead of terminating it.

Python pass: This statement allows the syntactical writing of code while intending to bypass its execution. It is also recognized as a null operation, as no action is taken when the pass statement is executed.

Write a code to display the contents of a file in reverse?
To display the contents of a file in reverse, the following code can be used:
filename = "filename.txt"
with open(filename, "r") as file:
    lines = file.readlines()

for line in reversed(lines):
    print(line.rstrip())
    
or

def display_file_in_reverse(file_path):
    try:
        # Open the file in read mode
        with open(file_path, 'r') as file:
            # Read the contents of the file
            content = file.read()

            # Reverse the content
            reversed_content = content[::-1]

            # Display the reversed content
            print(reversed_content)

    except FileNotFoundError:
        print(f"File not found: {file_path}")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example: Replace 'your_file.txt' with the path to your file
file_path = 'your_file.txt'
display_file_in_reverse(file_path)

How will you remove duplicate elements from a list?
To remove duplicate elements from the list we use the set() function.

Consider the below example:
demo_list = [5, 4, 4, 6, 8, 12, 12, 1, 5]
unique_list = list(set(demo_list))
output = [1, 5, 6, 8, 12]

or

original_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = []
for item in original_list:
    if item not in unique_list:
        unique_list.append(item)

or
using loop

original_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = []
for item in original_list:
    if item not in unique_list:
        unique_list.append(item)


or 

using comprehension

original_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = []
[unique_list.append(item) for item in original_list if item not in unique_list]

or

using dict
original_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(dict.fromkeys(original_list))


How to delete files in python?
You need to import the OS Module and use os.remove() function for deleting a file in python.
consider the code below:
import os
os.remove("file_name.txt")

or

import os

def delete_file(file_path):
    try:
        # Use os.remove() to delete the file
        os.remove(file_path)
        print(f"File '{file_path}' deleted successfully.")
    except FileNotFoundError:
        print(f"File not found: {file_path}")
    except PermissionError:
        print(f"Permission error: Unable to delete file {file_path}")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example: Replace 'your_file.txt' with the path to the file you want to delete
file_to_delete = 'your_file.txt'
delete_file(file_to_delete)



Write a Python program to count the total number of lines in a text file?
Refer the code below to count the total number of lines in a text file-

def file_count(fname):
    with open(fname) as f:
        for i, _ in enumerate(f):
            pass
    return i + 1

print("Total number of lines in the text file:",
file_count("file.txt"))

or

def count_lines(file_path):
    try:
        # Open the file in read mode
        with open(file_path, 'r') as file:
            # Use the readlines() method to read all lines into a list
            lines = file.readlines()

            # Count the number of lines in the list
            num_lines = len(lines)

            # Display the result
            print(f"The file '{file_path}' has {num_lines} lines.")

    except FileNotFoundError:
        print(f"File not found: {file_path}")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example: Replace 'your_file.txt' with the path to your text file
file_path = 'your_file.txt'
count_lines(file_path)



Write a code to sort a numerical list in Python?
The following code can be used to sort a numerical list in Python:
numbers = ["2", "5", "7", "8", "1"]
numbers = [int(i) for i in numbers]
numbers.sort()
print(numbers)

or

# Original numerical list
original_list = [4, 2, 7, 1, 9, 5]

# Sort the list using sorted() function
sorted_list = sorted(original_list)

# Display the sorted list
print("Original List:", original_list)
print("Sorted List:", sorted_list)

or

# Original numerical list
original_list = [4, 2, 7, 1, 9, 5]

# Use the sort() method to sort the list in-place
original_list.sort()

# Display the sorted list
print("Original List (now sorted):", original_list)


Can you write an efficient code to count the number of capital letters in a file?
The normal solution for this problem statement would be as follows:

with open(SOME_LARGE_FILE) as countletter:
count = 0
text = countletter.read()
for character in text:
    if character.isupper():
        count += 1


or

def count_capital_letters(file_path):
    try:
        # Open the file in read mode
        with open(file_path, 'r') as file:
            # Initialize the counter for capital letters
            capital_count = 0

            # Read the file character by character
            for char in file.read():
                # Check if the character is an uppercase letter
                if char.isupper():
                    capital_count += 1

            # Display the result
            print(f"The file '{file_path}' has {capital_count} capital letters.")

    except FileNotFoundError:
        print(f"File not found: {file_path}")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example: Replace 'your_file.txt' with the path to your text file
file_path = 'your_file.txt'
count_capital_letters(file_path)

        
How will you reverse a list in Python?
To reverse a list in Python, you can use the slicing technique. Here’s a brief explanation of the process:

Start with the original list that you want to reverse.
Use the slicing syntax [::-1] to create a new list that includes all elements from the original list in reverse order.

Assign the reversed list to a new variable or overwrite the original list with the reversed version.
original_list = [1, 2, 3, 4, 5]
reversed_list = original_list[::-1]

How will you remove the last object from a list in Python?
my_list = [1, 2, 3, 4, 5]
my_list.pop()
Here, −1 represents the last element of the list. Hence, the pop() function removes the last object (obj) from the list.

Print a list without last element?
def print_list_without_last(lst):
    # Use slicing to print the list without the last element
    print(lst[:-1])

# Test the function
my_list = [1, 2, 3, 4, 5]
print_list_without_last(my_list)

Print a list without 1st element?
def print_list_without_first(lst):
    # Use slicing to print the list without the first element
    print(lst[1:])

# Test the function
my_list = [1, 2, 3, 4, 5]
print_list_without_first(my_list)


Write a Python program to calculate the sum of a list of numbers?
def sum(num):
    if len(num) == 1:
        return num[0]  # With only one element in the list, the sum result will be equal to the element.
    else:
        return num[0] + sum(num[1:])

print(sum([2, 4, 5, 6, 7]))

or using builtin sum function

# Sample list of numbers
numbers = [1, 2, 3, 4, 5]

# Calculate the sum using the sum() function
total_sum = sum(numbers)

# Display the result
print(f"The sum of the numbers is: {total_sum}")

or using loop

# Sample list of numbers
numbers = [1, 2, 3, 4, 5]

# Initialize the sum
total_sum = 0

# Calculate the sum using a loop
for num in numbers:
    total_sum += num

# Display the result
print(f"The sum of the numbers is: {total_sum}")


Write a program in Python to check if a number is prime?
The below code is used to check if a number is prime or not

num = 13
if num > 1:
    for i in range(2, int(num/2)+1):
        if (num % i) == 0:
            print(num, "is not a prime number")
            break
    else:
        print(num, "is a prime number")
else:
    print(num, "is not a prime number")
    
Create a Python sorting algorithm for a dataset of numbers.
code to sort a list in Python:

my_list = ["8", "4", "3", "6", "2"]
my_list = [int(i) for i in list]
my_list.sort()
print (my_list)

Write a Program to print ASCII Value of a character in python?
Check the below code to print ASCII value:
x= 'a'
# print the ASCII value of assigned character stored in x
print(" ASCII value of '" + x + "' is", ord(x))
Output: 65

or

# Input: a single character
user_char = input("Enter a character: ")

# Get the ASCII value using the ord() function
ascii_value = ord(user_char)

# Display the result
print(f"The ASCII value of '{user_char}' is: {ascii_value}")