top of page
realcode4you

Python Code Review With Anaconda | Python Programming Help | Realcode4you

Table of Content

  1. Installation

  2. Basics

  3. Iterables

  4. Numpy (for math and matrix operations)

  5. Matplotlib (for plotting)

1. Installation

Anaconda for environment management https://www.anaconda.com/

common commands

conda env list <– list all environments 
conda create -n newenv python=3.8 <– create new environment 
conda enc create -f env.yml <– create environment from config file 
conda activate envname <– activate a environment
conda deactivate <– exit environment 
pip install packagename <– install package for current environment 
jupyter notebook <– open jupyter in current environment

Package installation using conda/pip

Recommended IDEs Spyder (in-built in Anaconda)

Pycharm (the most popular choice, compatible with Anaconda)


Common anaconda commands

#conda env list 
#conda create -n name python=3.8 
#conda env create -f env.yml 
#conda activate python2.7 
#conda deactivate 
#install packages 
#pip install 

2. Basics

https://www.w3schools.com/python/

# input and output 
name = input() 
print("hello, " + name) 

Output:

224N hello, 224N


# print multiple variables separated by a space 
print("hello", name, 1, 3.0, True) 

Output:

hello 224N 1 3.0 True


# line comment 
""" 
block comments 
"""

Output:

'\nblock \ncomments\n'


# variables don't need explicit declaration 
var = "hello"       # string 
var = 10.0           # float 
var = 10              # int 
var = True          # boolean 
var = [1,2,3]       # pointer to list 
var = None        # empty pointer

# type conversions 
var = 10 
print(int(var)) 
print(str(var)) 
print(float(var))

Output:

10

10

10.0


 # basic math operations
var = 10
print("var + 4 =", 10 + 4)
print("var - 4 =", 10 - 4)
print("var * 4 =", 10 * 4)
print("var ^ 4=", 10 ** 4)
print("int(var) / 4 =", 10//4) # // for int division
print("float(var) / 4 =", 10/4) # / for float division
# All compound assignment operators available
# including += -= *= **= /= //=
# pre/post in/decrementers not available (++ --)

Output:

var + 4 = 14

var - 4 = 6

var * 4 = 40

var ^ 4= 10000

int(var) / 4 = 2

float(var) / 4 = 2.5


# basic boolean operations include "and", "or", "not"
print("not True is", not True)
print("True and False is", True and False)
print("True or False is", True or False)

Output:

not True is False

True and False is False

True or False is True


# String operations
# '' and "" are equivalent
s = "String"
#s = 'Mary said "Hello" to John'
#s = "Mary said \"Hello\" to John"

# basic
print(len(s)) # get length of string and any iterable type
print(s[0]) # get char by index
print(s[1:3]) # [1,3)
print("This is a " + s + "!")

# handy tools
print(s.lower())
print(s*4)
print("ring" in s)
print(s.index("ring"))

# slice by delimiter
print("I am a sentence".split(" "))
# concatenate a list of string using a delimiter
print("...".join(['a','b','c']))

# formatting variables
print("Formatting a string like %.2f"%(0.12345))
print(f"Or like {s}!")

Output:

6

S

tr

This is a String!

string

StringStringStringString

True

2

['I', 'am', 'a', 'sentence']

a…b…c

Formatting a string like 0.12

Or like String!


# control flows
# NOTE: No parentheses or curly braces
# Indentation is used to identify code blocks
# So never ever mix spaces with tabs
for i in range(0,5):
for j in range(i, 5):
print("inner loop")
print("outer loop")

# if-else
var = 10
if var > 10:
	print(">")
elif var == 10:
	print("=")
else:
	print("<")

Output: =


# use "if" to check null pointer or empty arrays
var = None
if var:
	print(var)
var = []
if var:
	print(var)
var = "object"
if var:
	print(var)

Output:

object


# while-loop
var = 5
while var > 0:
	print(var)
	var -=1

Output:

5

4

3

2

1


# for-loop
for i in range(3): # prints 0 1 2
	print(i)
"""
equivalent to
for (int i = 0; i < 3; i++)
"""
print("-------")
# range (start-inclusive, stop-exclusive, step)
for i in range(2, -3, -2):
	print(i)
"""
equivalent to
for (int i = 2; i > -3; i-=2)
"""

output:

0

1

2

-------

2

0

-2


# define function
def func(a, b):
	return a + b
func(1,3)

output:

4


# use default parameters and pass values by parameter name
def rangeCheck(a, min_val = 0, max_val=10):
	return min_val < a < max_val # syntactic sugar
rangeCheck(5, max_val=4)

Output:

False


# define class
class Foo:
	# optinal constructor
	def __init__(self, x):
		# first parameter "self" for instance reference, like "this" in JAVA
		self.x = x
	# instance method
	def printX(self): 
		print(self.x)
	# class methods, most likely you will never need this
	@classmethod
	def printHello(self):
		print("hello")
obj = Foo(6)
obj.printX()

Output:

6


# class inheritance - inherits variables and methods
# You might need this when you learn more PyTorch
class Bar(Foo):
	pass
obj = Bar(3)
obj.printX()

Output:

3



3. Iterables

alist = list() # linear, size not fixed, not hashable
atuple = tuple() # linear, fixed size, hashable
adict = dict() # hash table, not hashable, stores (key,value) pairs
aset = set() # hash table, like dict but only stores keys
acopy = alist.copy() # shallow copy
print(len(alist)) # gets size of any iterable type

Output:

0


# examplar tuple usage
# creating a dictionary to store ngram counts
d = dict()
d[("a","cat")] = 10
d[["a","cat"]] = 11

Output:


"""
List: not hashable (i.e. can't use as dictionary key)
	dynamic size
	allows duplicates and inconsistent element types
	dynamic array implementation
"""

# list creation
alist = [] # empty list, equivalent to list()
alist = [1,2,3,4,5] # initialized list

print(alist[0])
alist[0] = 5
print(alist)
print("-"*10)
# list indexing
print(alist[0]) # get first element (at index 0)
print(alist[-2]) # get last element (at index len-1)
print(alist[3:]) # get elements starting from index 3 (inclusive)
print(alist[:3]) # get elements stopping at index 3 (exclusive)
print(alist[2:4]) # get elements within index range [2,4)
print(alist[6:]) # prints nothing because index is out of range
print(alist[::-1]) # returns a reversed list
print("-"*10)
# list modification
alist.append("new item") # insert at end
alist.insert(0, "new item") # insert at index 0
alist.extend([2,3,4]) # concatenate lists
# above line is equivalent to alist += [2,3,4]
alist.index("new item") # search by content
alist.remove("new item") # remove by content
alist.pop(0) # remove by index
print(alist)

print("-"*10)
if "new item" in alist:
	print("found")
else:
print("not found")

print("-"*10)
# list traversal
for ele in alist:
	print(ele)

print("-"*10)
# or traverse with index
for i, ele in enumerate(alist):
	print(i, ele)

output:

1

[5, 2, 3, 4, 5]

----------

5

4

[4, 5]

[5, 2, 3]

[3, 4]

[]

[5, 4, 3, 2, 5]

----------

[2, 3, 4, 5, 'new item', 2, 3, 4]

----------

found

----------

2

3

4

5

new item

2

3

4

----------

0 2

1 3

2 4

3 5

4 new item

5 2

6 3

7


 """
Tuple: hashable (i.e. can use as dictionary key)
fixed size (no insertion or deletion)
"""
# it does not make sense to create empty tuples
atuple = (1,2,3,4,5)
# or you can cast other iterables to tuple
atuple = tuple([1,2,3])
# indexing and traversal are same as list

 """
Named tuples for readibility
"""
from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
print(pt1.x, pt1.y)

output:

1.0 5.0


"""
Dict: not hashable
	dynamic size
	no duplicates allowed
	hash table implementation which is fast for searching
"""
# dict creation
adict = {} # empty dict, equivalent to dict()
adict = {'a':1, 'b':2, 'c':3}
print(adict)
# get all keys in dictionary
print(adict.keys())
# get value paired with key
print(adict['a'])
key = 'e'

# NOTE: accessing keys not in the dictionary leads to exception
if key in adict:
	print(adict[key])

# add or modify dictionary entries
adict['e'] = 10 # insert new key
adict['e'] = 5 # modify existing keys

print("-"*10)
# traverse keys only
for key in adict:
	print(key, adict[key])

print("-"*10)
# or traverse key-value pairs together
for key, value in adict.items():
	print(key, value)

print("-"*10)
# NOTE: Checking if a key exists
key = 'e'
if key in adict: # NO .keys() here please!
	print(adict[key])
else:
	print("Not found!")

output:

{'a': 1, 'b': 2, 'c': 3}

dict_keys(['a', 'b', 'c'])

1

----------

a 1

b 2

c 3

e 5

----------

a 1

b 2

c 3

e 5

----------

5


"""
Special dictionaries
"""
# set is a dictionary without values
aset = set()
aset.add('a')

# deduplication short-cut using set
alist = [1,2,3,3,3,4,3]
alist = list(set(alist))
print(alist)

# default_dictionary returns a value computed from a default function
# for non-existent entries
from collections import defaultdict
adict = defaultdict(lambda: 'unknown')
adict['cat'] = 'feline'
print(adict['cat'])
print(adict['dog'])

output:

[1, 2, 3, 4]

feline

unknown


# counter is a dictionary with default value of 0
# and provides handy iterable counting tools
from collections import Counter

# initialize and modify empty counter
counter1 = Counter()
counter1['t'] = 10
counter1['t'] += 1
counter1['e'] += 1
print(counter1)

print("-"*10)

# initialize counter from iterable
counter2 = Counter("letters to be counted")
print(counter2)
print("-"*10)

# computations using counters
print("1", counter1 + counter2)
print("2,", counter1 - counter2)
print("3", counter1 or counter2) # or for intersection, and for union

output:

Counter({'t': 11, 'e': 1})

----------

Counter({'e': 4, 't': 4, ' ': 3, 'o': 2, 'l': 1, 'r': 1, 's': 1, 'b': 1, 'c': 1,

'u': 1, 'n': 1, 'd': 1})

----------

1 Counter({'t': 15, 'e': 5, ' ': 3, 'o': 2, 'l': 1, 'r': 1, 's': 1, 'b': 1, 'c':

1, 'u': 1, 'n': 1, 'd': 1})

2, Counter({'t': 7})

3 Counter({'t': 11, 'e': 1})


 # sorting
a = [4,6,1,7,0,5,1,8,9]
a = sorted(a)
print(a)
a = sorted(a, reverse=True)
print(a)

output:

[0, 1, 1, 4, 5, 6, 7, 8, 9]

[9, 8, 7, 6, 5, 4, 1, 1, 0]


 # sorting
a = [("cat",1), ("dog", 3), ("bird", 2)]
a = sorted(a)
print(a)
a = sorted(a, key=lambda x:x[1])
print(a)

output:

[('bird', 2), ('cat', 1), ('dog', 3)]

[('cat', 1), ('bird', 2), ('dog', 3)]



 # useful in dictionary sorting
adict = {'cat':3, 'bird':1}
print(sorted(adict.items(), key=lambda x:x[1]))

output:

[('bird', 1), ('cat', 3)]


 # Syntax sugar: one-line control flow + list operation
sent = ["i am good", "a beautiful day", "HELLO FRIEND"]
"""
for i in range(len(sent)):
	sent[i] = sent[i].lower().split(" ")
"""
sent1 = [s.lower().split(" ") for s in sent]
print(sent1)
sent2 = [s.lower().split(" ") for s in sent if len(s) > 10]
print(sent2)
# Use this for deep copy!
# copy = [obj.copy() for obj in original]

output:

[['i', 'am', 'good'], ['a', 'beautiful', 'day'], ['hello', 'friend']]

[['a', 'beautiful', 'day'], ['hello', 'friend']]


# Syntax sugar: * operator for repeating iterable elements
print("-"*10)
print([1]*10)
# Note: This only repeating by value
# So you cannot apply the trick on reference types

# To create a double list
# DONT
doublelist = [[]]*10
doublelist[0].append(1)
print(doublelist)

# DO
doublelist = [[] for _ in range(10)]
doublelist[0].append(1)
print(doublelist)

output:

----------

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]

[[1], [], [], [], [], [], [], [], [], []]



4. Numpy

Very powerful python tool for handling matrices and higher dimensional arrays


# create arrays 
a = np.array([[1,2],[3,4],[5,6]])
print(a)
print(a.shape)
# create all-zero/one arrays
b = np.ones((3,4)) # np.zeros((3,4))
print(b)
print(b.shape)
# create identity matrix
c = np.eye(5)
print(c)
print(c.shape)

output:

[[1 2]

[3 4]

[5 6]]

(3, 2)

[[1. 1. 1. 1.]

[1. 1. 1. 1.]

[1. 1. 1. 1.]]

(3, 4)

[[1. 0. 0. 0. 0.]

[0. 1. 0. 0. 0.]

[0. 0. 1. 0. 0.]

[0. 0. 0. 1. 0.]

[0. 0. 0. 0. 1.]]

(5, 5)



# reshaping arrays
a = np.arange(8) # [8,] similar range() you use in for-loops
b = a.reshape((4,2)) # shape [4,2]
c = a.reshape((2,2,-1)) # shape [2,2,2] -- -1 for auto-fill
d = c.flatten() # shape [8,]
e = np.expand_dims(a, 0) # [1,8]
f = np.expand_dims(a, 1) # [8,1]
g = e.squeeze() # shape[8, ] -- remove all unnecessary dimensions
print(a)
print(b)

output:

[0 1 2 3 4 5 6 7]

[[0 1]

[2 3]

[4 5]

[6 7]]



# concatenating arrays
a = np.ones((4,3))
b = np.ones((4,3))
c = np.concatenate([a,b], 0)
print(c.shape)
d = np.concatenate([a,b], 1)
print(d.shape)

output:

(8, 3)

(4, 6)


 # one application is to create a batch for NN
x1 = np.ones((32,32,3))
x2 = np.ones((32,32,3))
x3 = np.ones((32,32,3))
# --> to create a batch of shape (3,32,32,3)
x = [x1, x2, x3]
x = [np.expand_dims(xx, 0) for xx in x] # xx shape becomes (1,32,32,3)
x = np.concatenate(x, 0)
print(x.shape)

output:

(3, 32, 32, 3)



# access array slices by index
a = np.zeros([10, 10])
a[:3] = 1
a[:, :3] = 2
a[:3, :3] = 3
rows = [4,6,7]
cols = [9,3,5]
a[rows, cols] = 4
print(a)

Output:

[[3. 3. 3. 1. 1. 1. 1. 1. 1. 1.]

[3. 3. 3. 1. 1. 1. 1. 1. 1. 1.]

[3. 3. 3. 1. 1. 1. 1. 1. 1. 1.]

[2. 2. 2. 0. 0. 0. 0. 0. 0. 0.]

[2. 2. 2. 0. 0. 0. 0. 0. 0. 4.]

[2. 2. 2. 0. 0. 0. 0. 0. 0. 0.]

[2. 2. 2. 4. 0. 0. 0. 0. 0. 0.]

[2. 2. 2. 0. 0. 4. 0. 0. 0. 0.]

[2. 2. 2. 0. 0. 0. 0. 0. 0. 0.]

[2. 2. 2. 0. 0. 0. 0. 0. 0. 0.]]



# transposition
a = np.arange(24).reshape(2,3,4)
print(a.shape)
print(a)
a = np.transpose(a, (2,1,0)) # swap 0th and 2nd axes
print(a.shape)
print(a)

Output:

(2, 3, 4)

[[[ 0 1 2 3]

[ 4 5 6 7]

[ 8 9 10 11]]


[[12 13 14 15]

[16 17 18 19]

[20 21 22 23]]]

(4, 3, 2)

[[[ 0 12]

[ 4 16]

[ 8 20]]


[[ 1 13]

[ 5 17]

[ 9 21]]


[[ 2 14]

[ 6 18]

[10 22]]


[[ 3 15]

[ 7 19]

[11 23]]]



4. Matplotlib

Powerful tool for visualization Many tutorials online. We only go over the basics here

import matplotlib.pyplot as plt
# line plot
x = [1,2,3]
y = [1,3,2]
plt.plot(x,y)

Output:



# scatter plot 
plt.scatter(x,y) 

Output:


# bar plots 
plt.bar(x,y)

Output:


Comments


bottom of page