This article is meant for experienced programmers to look at Python's syntaxes and those who need to refresh their memory. For novices, go to the next article.
I shall assume that you are familiar with some programming languages such as C/C++/Java. This article is NOT meant to be an introduction to programming.
I personally recommend that you learn a traditional general-purpose programming language (such as C/C++/Java) as foundation before learning scripting languages like Python/JavaScript/Perl/PHP because they are less structure than the traditional languages with many fancy features.
Syntax Summary and Comparison
- EOL Comments: Python's comment begins with a
'#'
and lasts until the end-of-line (EOL). Python does not support multi-line comments. On the other hand, Python supports triple-quoted multi-line string and you may use multi-line string for multi-line comment, or for commenting out lines of codes.C/C++/C#/Java end-of-line comment begins with'\\'
. They support multi-line comments via/* ... */
. - Strings and Multi-Line Strings: Python's string can be delimited by either single quotes (
'...'
) or double quotes ("..."
). Python also supports multi-line string, delimited by either triple-single ('''...'''
) or triple-double quotes ("""..."""
). Strings are immutable in Python.C/C++/C#/Java use double quotes for string and single quotes for character. The early versions do not support multi-line string. - Variable Type Declaration: Like most of the scripting interpreted languages (such as JavaScript/Perl), Python is dynamically typed. You do NOT need to declare variables (name and type) before using them. A variable is created via the initial assignment. Python associates types with the objects, not the variables, i.e., a variable can hold object of any types.
In C/C++/C#/Java, which are strong-type languages, you need to declare the name and type of a variable before using it.
- Data Types: Python support these data types:
int
(integers),float
(floating-point numbers),str
(String),bool
(boolean ofTrue
orFalse
), and more. - Statements: Python's statement ends with a newline.
C/C++/C#/Java's statement ends with a semi-colon (
;
) - Compound Statements and Indentation: Python uses indentation to indicate body-block, as follows:
header_1: # Headers are terminated by a colon statement_1_1 # Body blocks are indented (recommended to use 4 spaces) statement_1_2 ...... header_2: statement_2_1 statement_2_2 ...... # You can place the body-block in the same line, separating the statement by semi-colon (;) # This is NOT recommended. header_1: statement_1_1; statement_1_2; ...... header_2: statement_2_1; statement_2_2; ......
This syntax forces you to indent the program correctly which is crucial for reading your program. You can use space or tab for indentation (but not mixture of both). Each body level must be indented at the same distance. It is recommended to use 4 spaces for each level of indentation.C/C++/C#/Java use braces{}
. - Assignment Operator:
=
(assign RHS value to LHS variable) - Arithmetic Operators:
+
(add),-
(subtract),*
(multiply),/
(divide),%
(modulus),//
(integer divide),**
(exponent). But++
(increment) and--
(decrement) are NOT supported.C/C++/Java do int divide with twoint
's. They support exponentiation via library function. - Compound Assignment Operators:
+=
,-=
,*=
,/=
,%=
,//=
,**=
. - Comparison Operators:
==
,!=
,<
,<=
,>
,>=
,in
(check if a value is in a collection),not in
,is
(check if two variables point to the same object),not is
. - Logical Operators
:
and
,or
,not
.C/C++/C#/Java use&&
,||
and!
. - Conditional's:
# if-then-else if test: # no parentheses needed for test true_block else: # Optional false_block # Nested-if if test_1: block_1 elif test_2: # "elif" is a keyword block_2 ...... elif test_n: block_n else: else_block # Shorthand if-then-else tenary operator true_expr if test else false_expr # C/C++/C#/Java use tenary operator: test ? true_value : false_value
- Loops:
# while-do loop while test: # no parentheses needed for test true_block else: # Optional, run only if no break encountered else_block # for-each loop for item in sequence: true_block else: # Optional, run only if no break encountered else_block
Python does NOT support the traditional C-likefor
-loop with index:for (int i; i < n; ++i) { body }
. - List: Python supports variable-size dynamic array via a built-in data structure called
list
, denoted aslst
=[v1, v2, ..., vn]
. List is similar to C/C++/C#/Java's array but NOT fixed-size. You can refer to an element vialst[i]
orlst[-i]
, or sub-list vialst[m:n:step]
. You can use built-in functions such aslen(lst)
,sum(lst)
,min(lst)
. - Data Structures:
- List:
[v1, v2, ...]
: mutable dynamic array. - Tuple:
(v1, v2, v3, ...)
: Immutable fix-sized array. - Dictionary or Associative Array:
{k1:v1, k2:v2, ...}
: mutable key-value pairs, associative array, map. - Set:
{k1, k2, ...}
: mutable array with unique key.
- List:
- Sequence (String, Tuple, List) Operators and Functions:
in
,not in
: membership test - check if a value is in a collection.+
: concatenation*
: repetition[i]
,[-i]
: indexing[m:n:step]
: slicinglen(seq)
,min(seq)
,max(seq)
seq.index()
,seq.count()
- Mutable Sequences (list) only Operators and Functions:
- Assignment via
[i]
,[-i]
(indexing) and[m:n:step]
(slicing) - Assignment via
=
,+=
(compound concatenation),*=
(compound repetition) del
: deletemseq.clear()
,mseq.append()
,mseq
.extend()
,mseq.insert()
,mseq.remove()
,mseq.pop()
,mseq.copy()
,mseq.reverse()
- Assignment via
- Function Definition:
def functionName(*args, **kwargs): # Positional and keyword arguments body return return_value
Example grade_statistics.py
- Basic Syntaxes and Constructs
This example repeatably prompts user for grade (between 0 and 100 with input validation). It then computes the sum, average, minimum, and print the horizontal histogram.
This example illustrates the basic Python syntaxes and constructs, such as comment, statement, block indentation, conditional if-else
, for
-loop, while
-loop, input/output, string, list
and function.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
grade_statistics - Grade statistics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prompt user for grades (0-100 with input validation) and compute the sum, average,
minimum, and print the horizontal histogram.
An example to illustrate basic Python syntaxes and constructs, such as block indentation,
conditional, for-loop, while-loop, input/output, list and function.
Usage: ./grade_statistics.py (Unix/macOS)
python3 grade_statistics.py (All Platforms)
"""
# Define all the functions before using them
def my_sum(lst):
"""Return the sum of the given list."""
sum = 0
for item in lst: sum += item
return sum
def my_average(lst):
"""Return the average of the given list."""
return my_sum(lst)/len(lst) # float
def my_min(lst):
"""Return the minimum of the given lst."""
min = lst[0]
for item in lst:
if item < min: # Parentheses () not needed for test
min = item
return min
def print_histogram(lst):
"""Print the horizontal histogram."""
# Create a list of 10 bins to hold grades of 0-9, 10-19, ..., 90-100.
# bins[0] to bins[8] has 10 items, but bins[9] has 11 items.
bins = [0]*10 # Use repetition operator (*) to create a list of 10 zeros
# Populate the histogram bins from the grades in the given lst.
for grade in lst:
if grade == 100: # Special case
bins[9] += 1
else:
bins[grade//10] += 1 # Use // for integer divide to get a truncated int
# Print histogram
# 2D pattern: rows are bins, columns are value of that particular bin in stars
for row in range(len(bins)): # [0, 1, 2, ..., len(bins)-1]
# Print row header
if row == 9: # Special case
print('{:3d}-{:<3d}: '.format(90, 100), end='') # Formatted output (new style), no newline
else:
print('{:3d}-{:<3d}: '.format(row*10, row*10+9), end='') # Formatted output, no newline
# Print one star per count
for col in range(bins[row]): print('*', end='') # no newline
print() # newline
# Alternatively, use str's repetition operator (*) to create the output string
#print('*'*bins[row])
def main():
"""The main function."""
# Create an initial empty list for grades to receive from input
grade_list = []
# Read grades with input validation
grade = int(input('Enter a grade between 0 and 100 (or -1 to end): '))
while grade != -1:
if 0 <= grade <= 100: # Python support this comparison syntax
grade_list.append(grade)
else:
print('invalid grade, try again...')
grade = int(input('Enter a grade between 0 and 100 (or -1 to end): '))
# Call functions and print results
print('---------------')
print('The list is:', grade_list)
print('The minimum is:', my_min(grade_list))
print('The minimum using built-in function is:', min(grade_list)) # Using built-in function min()
print('The sum is:', my_sum(grade_list))
print('The sum using built-in function is:', sum(grade_list)) # Using built-in function sum()
print('The average is: %.2f' % my_average(grade_list)) # Formatted output (old style)
print('The average is: {:.2f}'.format(my_average(grade_list))) # Formatted output (new style)
print('---------------')
print_histogram(grade_list)
# Ask the Python interpreter to run the main() function
if __name__ == '__main__':
main()
To run the Python script on command-line (BUT I suggest that you run it under an IDE, such as VS Code):
# (All platforms) Invoke Python Interpreter to run the script $ cd /path/to/project_directory $ python3 grade_statistics.py // or py (in windows), or python # (Unix/macOS/Cygwin) Set the script to executable, and execute the script directly $ cd /path/to/project_directory $ chmod u+x grade_statistics.py $ ./grade_statistics.py
The expected output is:
$ Python3 grade_statistics.py Enter a grade between 0 and 100 (or -1 to end): 9 Enter a grade between 0 and 100 (or -1 to end): 999 invalid grade, try again... Enter a grade between 0 and 100 (or -1 to end): 101 invalid grade, try again... Enter a grade between 0 and 100 (or -1 to end): 8 Enter a grade between 0 and 100 (or -1 to end): 7 Enter a grade between 0 and 100 (or -1 to end): 45 Enter a grade between 0 and 100 (or -1 to end): 90 Enter a grade between 0 and 100 (or -1 to end): 100 Enter a grade between 0 and 100 (or -1 to end): 98 Enter a grade between 0 and 100 (or -1 to end): -1 --------------- The list is: [9, 8, 7, 45, 90, 100, 98] The minimum is: 7 The minimum using built-in function is: 7 The sum is: 357 The sum using built-in function is: 357 The average is: 51.00 --------------- 0-9 : *** 10-19 : 20-29 : 30-39 : 40-49 : * 50-59 : 60-69 : 70-79 : 80-89 : 90-100: ***
How It Works
- #!/usr/bin/env python3 (Line 1) is applicable to the Unix environment only. It is known as the Hash-Bang (or She-Bang) for specifying the path of the Python Interpreter, so that the script can be executed directly as a standalone program.
- # -*- coding: UTF-8 -*- (Line 2, optional) specifies the source encoding scheme for saving the source file. We choose and recommend UTF-8 for i18n (internationalization). This special format is recognized by many editors for saving the source code in the specified encoding format.
- Doc-String (Line 3-13): The script begins with the so-called documentation string, or doc-string, to provide the documentation for this module. Doc-string is a multi-line string (delimited by triple single/double quotes), which can be extracted from the source file to create documentation. In this way, the documentation is maintained in the source code together with the code.
- def my_sum(lst): (Line 15-19): We define a function called
my_sum()
which takes alist
and return the sum of the items. It uses a for-each-item-in loop to iterate through all the items of the givenlist
. As Python is interpretative, you need to define the function first, before using it.- We choose the function name
my_sum(list)
to differentiate from the built-in functionsum(list)
. sum
is an built-in function in Python. Our local variablesum
shadows the system built-in within themy_sum
function.
- We choose the function name
- bins = [0]*10 (Line 38): Python supports repetition operator (
*
). This statement creates alist
of ten zeros. Repetition operator (*
) can be apply on string (Line 59). - for row in range(len(bins)): (Line 48, 56): Python supports only
for-in
loop. It does NOT support the traditional C-likefor
-loop with index. Hence, we need to use the built-inrange(n)
function to create alist
of indexes[0, 1, ..., n-1]
, then apply thefor-in
loop on the indexedlist
. - 0 <= grade <= 100 (Line 68): Python supports this syntax for comparison. C/C++/C#/Java do not.
- There are few ways of printing:
- print() built-in function (Line 75-80):
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) # Print objects to the text-stream file (default standard output sys.stdout), # items are separated by sep (default space) and followed by end (default newline). # *objects denotes variable number of positional arguments packed into a tuple.
By default,print()
prints a newline at the end. You need to include argumentend=''
(empty string) to suppress the newline. - print(str.format()) (Line 51, 53): using Python 3's new style for formatting string via
str
class member functionstr.format()
. The string on which this method is called can contain texts, or replacement fields (place holders) delimited by braces{}
. Each replacement field contains either the numeric index of a positional argument, or the name of a keyword argument, with C-like format specifiers beginning with:
(instead of%
in C) such as:4d
for integer with width of 4,:6.2f
for floating-point number with width of 6 and 2 decimal places, and:-5s
for string with width of 5, and flags such as<
for left-align,>
for right-align,^
for center-align. - print('formatting-string' % args) (Line 81): Python 2's old style for formatted string using
%
operator. Theformatting-string
could contain C-like format-specifiers, such as%4d
for integer,%6.2f
for floating-point number,%5s
for string. This line is included in case you need to read old programs. I suggest you use the new Python 3's formatting style.
- print() built-in function (Line 75-80):
- grade = int(input('Enter ... ')) (Line 66, 72): You can read input from standard input device (default to keyboard) via the built-in
input()
function.input([promptStr]) # The optional promptStr argument is written to standard output without a trailing newline. # The function then reads a line from input, converts it to a string (stripping a trailing newline), # and returns the string.
As theinput()
function returns a string, we need to cast it toint
. - if __name__ == '__main__': (Line 87): When you execute a Python module via the Python Interpreter, the global variable
__name__
is set to'__main__'
. On the other hand, when a module is imported into another module, its__name__
is set to the module name. Hence, the above module will be executed if it is loaded by the Python interpreter, but not imported by another module. This is a good practice for running a module.
Example number_guess.py
- Guess a Number
This is a number guessing game. It illustrates nested-if (if-elif-else
), while
-loop with bool
flag, and random
module. For example,
Enter your guess (between 0 and 100): 50 Try lower... Enter your guess (between 0 and 100): 25 Try higher... Enter your guess (between 0 and 100): 37 Try higher... Enter your guess (between 0 and 100): 44 Try lower... Enter your guess (between 0 and 100): 40 Try lower... Enter your guess (between 0 and 100): 38 Try higher... Enter your guess (between 0 and 100): 39 Congratulation! You got it in 7 trials.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
number_guess - Number guessing game
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Guess a number between 0 and 99.
This example illustrates while-loop with boolean flag, nested-if, and importing random module.
Usage: ./number_guess.py
"""
import random # Using random.randint()
# Set up a secret number between 0 and 99
secret_number = random.randint(0, 99) # return a random int between [0, 99]
trial_number = 0 # number of trials
done = False # bool flag for loop control
while not(done):
trial_number += 1
number_in = (int)(input('Enter your guess (between 0 and 99): '))
if number_in == secret_number:
print('Congratulation!')
print('You got it in {} trials.'.format(trial_number)) # Formatted printing
done = True
elif number_in < secret_number:
print('Try higher...')
else:
print('Try lower...')
How It Works
- import random (Line 11): We are going to use an external module
random
'srandint()
functionto generate a secret number. In Python, you need to
import
the external module before using it. - random.randint(0, 99) (Line 14): Generate a random integer between
0
and99
(both inclusive). - done = False (Line 16): Python supports a
bool
type for boolean values ofTrue
orFalse
. We will use this boolean flag to control ourwhile
-loop. - while-loop (Line 18-28): The syntax is:
while boolean_test: # No need for () around the test loop_body
- nested-if (Line 21-28): The syntax is:
if boolean_test_1: # No need for () around the test block_1 elif boolean_test_2: block_2 ...... else: else_block
Take note that Python supportselif
keyword (instead of "else if
" in C/C++/Java).
Example magic_number.py
- Check if Number Contains a Magic Digit
This example prompts user for a number, and checks if the number contains a magic digit. This example illustrates function, int
and str
operations. For example,
Enter a number: 123456789 123456789 is a magic number 123456789 is a magic number
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
magic_number - Check if the given number contains a magic digit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prompt user for a number, and check if the number contains a magic digit.
Usage: ./magic_number.py
"""
def isMagic(number:int, magicDigit:int = 8) -> bool:
"""Check if the given number contains the digit magicDigit.
Arguments:
number - positive int only
magicDigit - single-digit int (default is 8)
"""
while number > 0:
# extract and drop each digit
if number % 10 == magicDigit:
return True # break loop
else:
number //= 10 # integer division
return False
def isMagicStr(numberStr:str, magicDigit:str = '8') -> bool:
"""Check if the given number string contains the magicDigit
Arguments:
numberStr - a numeric str
magicDigit - a single-digit str (default is '8')
"""
return magicDigit in numberStr # Use built-in sequence operator 'in'
def main():
"""The main function"""
# Prompt and read input string as int
numberIn = int(input('Enter a number: '))
# Use isMagic()
if isMagic(numberIn):
print('{} is a magic number'.format(numberIn))
else:
print('{} is NOT a magic number'.format(numberIn))
#print(isMagic(numberIn)); # default magicDigit=8
#print(isMagic(numberIn, 0)); # override default
# Use isMagicStr()
if isMagicStr(str(numberIn), '9'): # Try removing str()
print('{} is a magic number'.format(numberIn))
else:
print('{} is NOT a magic number'.format(numberIn))
# Run the main function
if __name__ == '__main__':
main()
How It Works
- We implemented two versions of function to check for magic number - an
int
version (Line 10) and astr
version (Line 25) - for academic purpose.Function Overloading: Python does not support function overloading, as Python's function parameters do not have a data type. You need to write different versions with different function names. - def isMagic(number:int, magicDigit:int = 8) -> bool: (Line 10): The highlight parts are known as type hint annotations. They are ignored by Python Interpreter, and merely serve as documentation. Python supports default value for function parameter, as in
magicDigit
(with default value of 8).
Example hex2dec.py
- Hexadecimal To Decimal Conversion
This example prompts user for a hexadecimal (hex) string, and prints its decimal equivalent. It illustrates for-loop with index, nested-if, string operation and dictionary (associative array). For example,
Enter a hex string: 1abcd The decimal equivalent for hex "1abcd" is: 109517 The decimal equivalent for hex "1abcd" using built-in function is: 109517
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
hex2dec - hexadecimal to decimal conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prompt user for a hex string, and print its decimal equivalent
This example illustrates for-loop with index, nested-if, string operations and dictionary.
Usage: ./hex2dec.py
"""
import sys # Using sys.exit()
dec = 0 # Accumulating from each hex digit
dictHex2Dec = {'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15} # lookup table for hex to dec
# Prompt and read hex string
hexStr = input('Enter a hex string: ')
hexStrLen = len(hexStr)
# Process each hex digit from the left (most significant digit)
for hexDigitIdx in range(hexStrLen): # hexDigitIdx = 0, 1, 2, ..., hexStrlen-1
hexDigit = hexStr[hexDigitIdx] # Extract each 1-character string
hexExpFactor = 16 ** (hexStrLen - 1 - hexDigitIdx) # ** for power or exponent
if '1' <= hexDigit <= '9': # Python supports chain comparison
dec += int(hexDigit) * hexExpFactor
elif hexDigit == '0':
pass # Need a dummy statement for do nothing
elif 'A' <= hexDigit <= 'F':
dec += (ord(hexDigit) - ord('A') + 10) * hexExpFactor # ord() returns the Unicode number
elif 'a' <= hexDigit <= 'f':
dec += dictHex2Dec[hexDigit] * hexExpFactor # Look up from dictionary
else:
print('error: invalid hex string')
sys.exit(1) # Return a non-zero value to indicate abnormal termination
print('The decimal equivalent for hex "{}" is: {}'.format(hexStr, dec)) # Formatted output
# Using built-in function int(str, radix)
print('The decimal equivalent for hex "{}" using built-in function is: {}'.format(hexStr, int(hexStr, 16)))
How It Works
- The conversion formula is:
hn-1hn-2...h2h1h0 = hn-1×16n-1 + hn-2×16n-2 + ... + h2×162 + h1×161 + h0×160
, wherehi ∈ {0-9, A-F, a-f}
. import sys
(Line 11): We are going to use external modulesys
'sexit()
function to terminate the program for invalid input. In Python, we need to import the module (external library) before using it.for hexDigitIdx in range(hexStrLen):
(Line 21): Python does not support the traditional C-likefor
-loop with index. It supports onlyfor item in lst
loop to iterate through eachitem
in thelst
. We use the built-in functionrange(n)
to generate a list[0, 1, 2, ..., n-1]
, and then iterate through each index in the generated list.- In Python, we can iterate through each character of a string (which is also a sequence) via the
for-in
loop, e.g.,str = 'hello' for ch in str: # Iterate through each character of the str print(ch)
For this example, we cannot use the above as we need the index of the character to perform conversion. hexDigit = hexStr[hexDigitIdx]
(Line 22): In Python, we can use indexing operatorstr[i]
to extract thei
-th character. Take note that Python does not support character type, but treats character as a 1-character string.hexExpFactor = 16 ** (hexStrLen - 1 - hexDigitIdx)
(Line 23): Python supports exponent (or power) operator in the form of**
. Take note that string index begins from 0, and increases from left-to-right. On the other hand, the hex digit's exponent begins from 0, but increases from right-to-left.- There are
23
cases of 1-character strings forhexDigit
,'0'-'9'
,'A'-'F'
,'a'-'z'
, and others (error), which can be handled by 5 cases of nested-if as follows:- '1'-'9' (Line 24): we convert the string
'1'-'9'
toint
1-9
viaint()
built-in function. - '0' (Line 26): do nothing. In Python, you need to include a dummy statement called
pass
(Line 27) in the body block. - 'A'-'F' (Line 28): To convert 1-character string
'A'-'F'
toint
10-15
, we use theord(ch)
built-in function to get the Unicodeint
ofch
, subtract by the base'A'
and add 10. - 'a'-'f' (Line 30): Python supports a data structure called dictionary (or associative array), which contains key-value pairs. We created a dictionary
dictHex2Dec
(Line 14) to map'a'
to10
,'b'
to11
, and so on. We can then reference the dictionary viadic[key]
to retrieve its value (Line 31). Take note that an associative array is similar to an array. An array supports only numeric keys 0, 1, 2, ... but an associative array can support any keys. - Others (Line 32): we use
sys.exit(1)
to terminate the program. We return a non-zero code to indicate abnormal termination.
- '1'-'9' (Line 24): we convert the string
Example bin2dec.py
- Binary to Decimal Conversion
This example prompts user for a binary string (with input validation), and print its decimal equivalent. For example,
Enter a binary string: 1011001110 The decimal equivalent for binary "1011001110" is: 718 The decimal equivalent for binary "1011001110" using built-in function is: 718
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
bin2dec - binary to decimal conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prompt user for a binary string, and print its decimal equivalent
Usage: ./bin2dec.py
"""
def validate(binStr:str) -> bool:
"""Check if the given binStr is a binary string (containing '0' and '1' only)"""
for ch in binStr:
if not(ch == '0' or ch == '1'): return False
return True
def convert(binStr:str) -> int:
"""Convert the given validated binStr into its equivalent decimal"""
dec = 0 # Accumulate from each bit
# Process each bit from the left (most significant digit)
for bitIdx in range(len(binStr)): # bitIdx = 0, 1, 2, ..., len()-1
bit = binStr[bitIdx]
if bit == '1':
dec += 2 ** (len(binStr) - 1 - bitIdx) # ** for power
return dec
def main():
"""The main function"""
# Prompt and read binary string
binStr = input('Enter a binary string: ')
if not validate(binStr):
print('error: invalid binary string "{}"'.format(binStr))
else:
print('The decimal equivalent for binary "{}" is: {}'.format(binStr, convert(binStr)))
# Using built-in function int(str, radix)
print('The decimal equivalent for binary "{}" using built-in function is: {}'.format(binStr, int(binStr, 2)))
# Run the main function
if __name__ == '__main__':
main()
How It Works
- The conversion formula is:
bn-1bn-2...b2b1b0 = bn-1×2n-1 + bn-2×2n-2 + ... + b2×22 + b1×21 + b0×20
, wherebi ∈ {0, 1}
- You can use built-in function
int(str, radix)
to convert a numeric string from the givenradix
to decimal (Line 38).
Example dec2hex.py
- Decimal to Hexadecimal Conversion
This program prompts user for a decimal number, and print its hexadecimal equivalent. For example,
Enter a decimal number: 45678 The hex for decimal 45678 is: B26E The hex for decimal 45678 using built-in function is: 0xb26e
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
dec2hex - decimal hexadecimal to conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prompt user for a decimal number, and print its hexadecimal equivalent
Usage: ./dec2hex.py
"""
hexStr = '' # To be accumulated
hexChars = [ # Use this list as lookup table for converting 0-15 to 0-9A-F
'0','1','2','3', '4','5','6','7', '8','9','A','B', 'C','D','E','F'];
# Prompt and read decimal number
dec = int(input('Enter a decimal number: ')) # positive int only
decSave = dec # We will destroy dec
# Repeated modulus/division to get the hex digits in reverse order
while dec > 0:
hexDigit = dec % 16; # 0-15
hexStr = hexChars[hexDigit] + hexStr; # Append in front corresponds to reverse order
dec = dec // 16; # Integer division
print('The hex for decimal {} is: {}'.format(decSave, hexStr)) # Formatted output
# Using built-in function hex(decNumber)
print('The hex for decimal {} using built-in function is: {}'.format(decSave, hex(decSave)))
How It Works
- We use the modulus/division repeatedly to get the hex digits in reverse order.
- We use a look-up list (Line 11) to convert
int
0-15
to hex digit0-9A-F
. - You can use built-in function
hex(decNumber)
,oct(decNumber)
,bin(decNumber)
to convert decimal to hexadecimal, octal and binary, respectively; or use the more generalformat()
function. E.g.,>>> format(1234, 'x') # lowercase a-f '4d2' >>> format(1234, 'X') # uppercase A-F '4D2' >>> format(1234, 'o') '2322' >>> format(1234, 'b') '10011010010' >>> format(0x4d2, 'b') '10011010010' >>> hex(1234) '0x4d2' >>> oct(1234) '0o2322' >>> bin(1234) '0b10011010010' # Print a string in ASCII code >>> str = 'hello' >>> ' '.join(format(ord(ch), 'x') for ch in str) '68 65 6c 6c 6f'
Example wc.py
- Word Count
This example reads a filename from command-line and prints the line, word and character counts (like the wc
utility in Unix). It illustrates the text file input and text string processing.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
wc - word count
~~~~~~~~~~~~~~~
Read a file given in the command-line argument and print the number of
lines, words and characters - like the UNIX's wc utility.
Usage: ./wc.py <filename>
"""
# Check if a filename is given in the command-line arguments using "sys" module
import sys # Using sys.argv and sys.exit()
if len(sys.argv) != 2: # Command-line arguments are kept in a list named sys.argv
print('Usage: ./wc.py <filename>')
sys.exit(1) # Return a non-zero value to indicate abnormal termination
# You do not need to declare the name and type of variables.
# Variables are created via the initial assignments.
num_words = num_lines = num_chars = 0 # chain assignment
# Get input file name from list sys.argv
# sys.argv[0] is the script name, sys.argv[1] is the filename.
with open(sys.argv[1]) as infile: # 'with-as' closes the file automatically
for line in infile: # Process each line (including newline) in a for-in loop
num_lines += 1 # No ++ operator in Python?!
num_chars += len(line)
line = line.strip() # Remove leading and trailing whitespaces
words = line.split() # Split into a list using whitespace as delimiter
num_words += len(words)
# Various ways of printing results
print('Number of Lines is', num_lines) # Items separated by blank
print('Number of Words is: {0:5d}'.format(num_words)) # Python 3's new formatting style
print('Number of Characters is: %8.2f' % num_chars) # Python 2's old formatting style
# Invoke Unix utility 'wc' through shell command for comparison
from subprocess import call # Python 3
call(['wc', sys.argv[1]]) # Command in a list ['wc', filename]
import os # Python 2
os.system('wc ' + sys.argv[1]) # Command is a str
'wc filename'
How It Works
- import sys (Line 12): We use the
sys
module (@ https://docs.python.org/3/library/sys.html) from the Python's standard library to retrieve the command-line arguments kept inlist
sys.argv
, and to terminate the program viasys.exit()
. In Python, we need toimport
the module before using it. - Command-Line Arguments: The command-line arguments are stored in a variable
sys.argv
, which is alist
(Python's dynamic array). The first item of thelist
sys.argv[0]
is the script name, followed by the other command-line arguments. - if len(sys.argv) != 2: (Line 13): We use the built-in function
len(list)
to verify that the length of the command-line-argumentlist
is 2. - with open(sys.argv[1]) as infile: (Line 23): We open the file via a
with-as
statement, which closes the file automatically upon exit. - for line in infile: (Line 24): We use a
for-in
loop to process eachline
of theinfile
, whereline
belong to the built-in class "str
"(meant for string support @ https://docs.python.org/3/library/stdtypes.html#str). We use the
str
class' member functionsstrip()
to strip the leading and trailing white spaces; andsplit()
to split the string into alist
of words.str.strip([chars]) # Return a copy of the string with leading and trailing characters removed. # The optional argument chars is a string specifying the characters to be removed. # Default is whitespaces '\t\n '. str.split(sep=None, maxsplit=-1) # Return a list of the words in the string, using sep as the delimiter string. # If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements).
- We also invoke the Unix utility "
wc
" via external shell command in 2 ways: viasubprocess.call()
andos.system()
.
Example htmlescape.py
- Escape Reserved HTML Characters
This example reads the input and output filenames from the command-line and replaces the reserved HTML characters by their corresponding HTML entities. It illustrates file input/output and string substitution.
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
htmlescape - Escape the given html file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Replace the HTML reserved characters by their corresponding HTML entities.
" will be replaced by "
& will be replaced by &
< will be replaced by <
> will be replaced by >
Usage: ./htmlescape.py <infile> <outfile>
"""
import sys # Using sys.argv and sys.exit()
# Check if infile and outfile are given in the command-line arguments
if len(sys.argv) != 3:
print('Usage: ./htmlescape.py <infile> <outfile>')
sys.exit(1) # Return a non-zero value to indicate abnormal termination
# The "with-as" statement closes the files automatically upon exit.
with open(sys.argv[1]) as infile, open(sys.argv[2], 'w') as outfile:
for line in infile: # Process each line (including newline)
line = line.rstrip() # strip trailing (right) white spaces
# Encode HTML &, <, >, ". The order of substitution is important!
line = line.replace('&', '&') # Need to do first as the rest contain it
line = line.replace('<', '<')
line = line.replace('>', '>')
line = line.replace('"', '"')
outfile.write('{}\n'.format(line)) # write() does not output newline
How It Works
- import sys (Line 14): We
import
thesys
module (@ https://docs.python.org/3/library/sys.html). We retrieve the command-line arguments from thelist
sys.argv
, wheresys.argv[0]
is the script name; and usesys.exit()
(Line 18) to terminate the program. - with open(sys.argv[1]) as infile, open(sys.argv[2], 'w') as outfile: (Line 21): We use the
with-as
statement, which closes the files automatically upon exit, to open theinfile
for read (default) andoutfile
for write ('w'
). - for line in infile: (Line 22): We use a
for-in
loop to process eachline
of theinfile
, whereline
belongs to the built-in class "str
"(meant for string support @ https://docs.python.org/3/library/stdtypes.html#str). We use
str
class' member functionrstrip()
to strip the trailing (right) white spaces; andreplace()
for substitution.str.rstrip([chars]) # Return a copy of the string with trailing (right) characters removed. # The optional argument chars is a string specifying the characters to be removed. # Default is whitespaces '\t\n '. str.replace(old, new[, count]) # Return a copy of the string with ALL occurrences of substring old replaced by new. # If the optional argument count is given, only the first count occurrences are replaced.
- Python 3.2 introduces a new
html
module, with a functionescape()
to escape HTML reserved characters.>>> import html >>> html.escape('<p>Test "Escape&"</p>') '<p>Test "Escape&"</p>'
Example files_rename.py
- Rename Files
This example renames all the files in the given directory using regular expression (regex). It illustrates directory/file processing (using module os
) and regular expression (using module re
).
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
files_rename - Rename files in the directory using regex
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rename all the files in the given directory (default to the current directory)
matching the regular expression from_regex by to_regex.
Usage: ./files_rename.py <from_regex> <to_regex> [<dir>|.]
Eg. Rename '.txt' to '.bak' in the current directory:
$ ./files_rename.py '\.txt' '.bak'
Eg. Rename files ending with '.txt' to '.bak' in directory '/temp'
$ ./files_rename.py '\.txt$' '.bak' '/temp'
Eg. Rename 0 to 9 with _0 to _9 via back reference (\n) in the current directory:
$ ./files_rename.py '([0-9])' '_\1'
"""
import sys # Using sys.argv, sys.exit()
import os # Using os.chdir(), os.listdir(), os.path.isfile(), os.rename()
import re # Regular expression: using re.sub()
if not(3 <= len(sys.argv) <= 4): # logical operators are 'and', 'or', 'not'
print('Usage: ./files_rename.py <from_regex> <to_regex> [<dir>|.]')
sys.exit(1) # Return a non-zero value to indicate abnormal termination
# Change directory, if given in the command-line argument
if len(sys.argv) == 4:
dir = sys.argv[3]
os.chdir(dir) # change current working directory
count = 0 # count of files renamed
for oldFilename in os.listdir(): # list current directory, non-recursive
if os.path.isfile(oldFilename): # process file only (not directory)
newFilename = re.sub(sys.argv[1], sys.argv[2], oldFilename) # compute the new filename
if oldFilename != newFilename:
count += 1
os.rename(oldFilename, newFilename) # do the rename
print(oldFilename, '->', newFilename) # print changes
print("Number of files renamed:", count)
How It Works
- import os (Line 20): We
import
theos
module (for operating system utilities @ https://docs.python.org/3/library/os.html), and use these functions:os.listdir(path='.') # Return a list containing the names of the entries in the directory given by path. # Default is current working directory denoted as '.' os.path.isfile(path) # Return True if path is an existing regular file (not a directory nor link). os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) # Rename the file or directory src to dst.
- import re (Line 21): We
import
the re module (for regular expression @ https://docs.python.org/3/library/re.html), and use this function:re.sub(pattern, replacement, string, count=0, flags=0) # default count=0 replaces all matches.
REFERENCES & RESOURCES
- The Python's mother site @ www.python.org; "The Python Documentation" @ https://www.python.org/doc/; "The Python Tutorial" @ https://docs.python.org/tutorial/; "The Python Language Reference" @ https://docs.python.org/reference/.
- Vernon L. Ceder, "The Quick Python Book", 2nd ed, 2010, Manning (Good starting guide for experience programmers who wish to learning Python).
- Mark Lutz, "Learning Python", 4th ed, 2009; "Programming Python", 4th ed, 2011; "Python Pocket Reference", 4th ed, 2010, O'reilly.