Python Programming Tutorials (BASIC + ADVANCE) - Learn From Scratch With Examples
Python Programming Tutorials (BASIC + ADVANCE) - Learn From Scratch With Examples
About
................................................................................................................................................
1
Chapter 1: Getting started with Python Language
...................................................................................... 2
Section 1.1: Getting Started
...........................................................................................................................................
2
Section 1.2: Creating variables and assigning values
................................................................................................ 6
Section 1.3: Block Indentation
.....................................................................................................................................
10
Section 1.4: Datatypes
................................................................................................................................................
11
Section 1.5: Collection Types
......................................................................................................................................
15
Section 1.6: IDLE - Python GUI
....................................................................................................................................
19
Section 1.7: User Input
................................................................................................................................................
21
Section 1.8: Built in Modules and Functions
.............................................................................................................. 21
Section 1.9: Creating a module
...................................................................................................................................
25
Section 1.10: Installation of Python 2.7.x and 3.x
....................................................................................................... 26
Section 1.11: String function - str() and repr()
........................................................................................................... 28
Section 1.12: Installing external modules using pip
................................................................................................... 29
Section 1.13: Help Utility
...............................................................................................................................................
31
Chapter 2: Python Data Types
............................................................................................................................
33
Section 2.1: String Data Type
.....................................................................................................................................
33
Section 2.2: Set Data Types
.......................................................................................................................................
33
Section 2.3: Numbers data type
................................................................................................................................
33
Section 2.4: List Data Type
.........................................................................................................................................
34
Section 2.5: Dictionary Data Type
.............................................................................................................................
34
Section 2.6: Tuple Data Type
.....................................................................................................................................
34
Chapter 3: Indentation
.............................................................................................................................................
35
Section 3.1: Simple example
.......................................................................................................................................
35
Section 3.2: How Indentation is Parsed
..................................................................................................................... 35
Section 3.3: Indentation Errors
...................................................................................................................................
36
Chapter 4: Comments and Documentation
.................................................................................................. 37
Section 4.1: Single line, inline and multiline comments
............................................................................................ 37
Section 4.2: Programmatically accessing docstrings
.............................................................................................. 37
Section 4.3: Write documentation using docstrings
................................................................................................ 38
Chapter 5: Date and Time
......................................................................................................................................
42
Section 5.1: Parsing a string into a timezone aware datetime object
.................................................................... 42
Section 5.2: Constructing timezone-aware datetimes
............................................................................................ 42
Section 5.3: Computing time di☐erences
.................................................................................................................. 44
Section 5.4: Basic datetime objects usage
............................................................................................................... 44
Section 5.5: Switching between time zones
.............................................................................................................. 45
Section 5.6: Simple date arithmetic
...........................................................................................................................
45
Section 5.7: Converting timestamp to datetime
...................................................................................................... 46
Section 5.8: Subtracting months from a date accurately
....................................................................................... 46
Section 5.9: Parsing an arbitrary ISO 8601 timestamp with minimal libraries
...................................................... 46
Section 5.10: Get an ISO 8601 timestamp
.................................................................................................................. 47
Section 5.11: Parsing a string with a short time zone name into a timezone
aware datetime object ................ 47
Section 5.12: Fuzzy datetime parsing (extracting datetime out of a text)
............................................................ 48
Section 5.13: Iterate over dates
..................................................................................................................................
49
Chapter 6: Date Formatting
..................................................................................................................................
50
Section 6.1: Time between two date-times
............................................................................................................... 50
Section 6.2: Outputting datetime object to string
.................................................................................................... 50
Section 6.3: Parsing string to datetime object
......................................................................................................... 50
Chapter 7: Enum
.................................................................................................................................................
51
Section 7.1: Creating an enum (Python 2.4 through 3.3)
......................................................................................... 51
Section 7.2: Iteration
.................................................................................................................................................
51
Chapter 8: Set
.................................................................................................................................................
52
Section 8.1: Operations on sets
..................................................................................................................................
52
Section 8.2: Get the unique elements of a list
.......................................................................................................... 53
Section 8.3: Set of Sets
................................................................................................................................................
53
Section 8.4: Set Operations using Methods and Builtins
......................................................................................... 53
Section 8.5: Sets versus multisets
..............................................................................................................................
55
Chapter 9: Simple Mathematical Operators
................................................................................................. 57
Section 9.1: Division
................................................................................................................................................
57
Section 9.2: Addition
................................................................................................................................................
58
Section 9.3: Exponentiation
........................................................................................................................................
59
Section 9.4: Trigonometric Functions
........................................................................................................................
60
Section 9.5: Inplace Operations
.................................................................................................................................
61
Section 9.6: Subtraction
..............................................................................................................................................
61
Section 9.7: Multiplication
...........................................................................................................................................
61
Section 9.8: Logarithms
..............................................................................................................................................
62
Section 9.9: Modulus
................................................................................................................................................
62
Chapter 10: Bitwise Operators
.............................................................................................................................
65
Section 10.1: Bitwise NOT
............................................................................................................................................
65
Section 10.2: Bitwise XOR (Exclusive OR)
.................................................................................................................. 66
Section 10.3: Bitwise AND
............................................................................................................................................
67
Section 10.4: Bitwise OR
..............................................................................................................................................
67
Section 10.5: Bitwise Left Shift
....................................................................................................................................
67
Section 10.6: Bitwise Right Shift
..................................................................................................................................
68
Section 10.7: Inplace Operations
................................................................................................................................
68
Chapter 11: Boolean Operators
............................................................................................................................
69
Section 11.1: `and` and `or` are not guaranteed to return a boolean
...................................................................... 69
Section 11.2: A simple example
...................................................................................................................................
69
Section 11.3: Short-circuit evaluation
.........................................................................................................................
69
Section 11.4: and
.................................................................................................................................................
70
Section 11.5: or
.................................................................................................................................................
70
Section 11.6: not
.................................................................................................................................................
71
Chapter 12: Operator Precedence
...................................................................................................................... 72
Section 12.1: Simple Operator Precedence Examples in python
............................................................................. 72
Chapter 13: Variable Scope and Binding
......................................................................................................... 73
Section 13.1: Nonlocal Variables
.................................................................................................................................
73
Section 13.2: Global Variables
....................................................................................................................................
73
Section 13.3: Local Variables
......................................................................................................................................
74
Section 13.4: The del command
.................................................................................................................................
75
Section 13.5: Functions skip class scope when looking up names
......................................................................... 76
Section 13.6: Local vs Global Scope
...........................................................................................................................
77
Section 13.7: Binding Occurrence
...............................................................................................................................
79
Chapter 14: Conditionals
.........................................................................................................................................
80
Section 14.1: Conditional Expression (or "The Ternary Operator")
......................................................................... 80
Section 14.2: if, elif, and else
.......................................................................................................................................
80
Section 14.3: Truth Values
...........................................................................................................................................
80
Section 14.4: Boolean Logic Expressions
................................................................................................................... 81
Section 14.5: Using the cmp function to get the comparison result of two
objects ............................................. 83
Section 14.6: Else statement
.......................................................................................................................................
83
Section 14.7: Testing if an object is None and assigning it
...................................................................................... 84
Section 14.8: If statement
............................................................................................................................................
84
Chapter 15: Comparisons
........................................................................................................................................
86
Section 15.1: Chain Comparisons
................................................................................................................................
86
Section 15.2: Comparison by `is` vs `==`
...................................................................................................................... 87
Section 15.3: Greater than or less than
...................................................................................................................... 88
Section 15.4: Not equal to
...........................................................................................................................................
88
Section 15.5: Equal To
.................................................................................................................................................
89
Section 15.6: Comparing Objects
...............................................................................................................................
89
Chapter 16: Loops
.................................................................................................................................................
91
Section 16.1: Break and Continue in Loops
................................................................................................................ 91
Section 16.2: For loops
................................................................................................................................................
93
Section 16.3: Iterating over lists
..................................................................................................................................
93
Section 16.4: Loops with an "else" clause
.................................................................................................................. 94
Section 16.5: The Pass Statement
..............................................................................................................................
96
Section 16.6: Iterating over dictionaries
.................................................................................................................... 97
Section 16.7: The "half loop" do-while
........................................................................................................................
98
Section 16.8: Looping and Unpacking
....................................................................................................................... 98
Section 16.9: Iterating di☐erent portion of a list with di☐erent step size
............................................................... 99
Section 16.10: While Loop
..........................................................................................................................................
100
Chapter 17: Arrays
................................................................................................................................................
102
Section 17.1: Access individual elements through indexes
..................................................................................... 102
Section 17.2: Basic Introduction to Arrays
.............................................................................................................. 102
Section 17.3: Append any value to the array using append() method
................................................................ 103
Section 17.4: Insert value in an array using insert() method
................................................................................ 103
Section 17.5: Extend python array using extend() method
................................................................................... 103
Section 17.6: Add items from list into array using fromlist() method
.................................................................. 104
Section 17.7: Remove any array element using remove() method
..................................................................... 104
Section 17.8: Remove last array element using pop() method
............................................................................ 104
Section 17.9: Fetch any element through its index using index() method
........................................................... 104
Section 17.10: Reverse a python array using reverse() method
........................................................................... 104
Section 17.11: Get array bu☐er information through bu☐er_info() method
........................................................ 105
Section 17.12: Check for number of occurrences of an element using count()
method .................................... 105
Section 17.13: Convert array to string using tostring() method
............................................................................ 105
Section 17.14: Convert array to a python list with same elements using
tolist() method .................................. 105
Section 17.15: Append a string to char array using fromstring() method
........................................................... 105
Chapter 18: Multidimensional arrays
.............................................................................................................. 106
Section 18.1: Lists in lists
............................................................................................................................................
106
Section 18.2: Lists in lists in lists in..
..........................................................................................................................
106
Chapter 19: Dictionary
............................................................................................................................................
108
Section 19.1: Introduction to Dictionary
................................................................................................................... 108
Section 19.2: Avoiding KeyError Exceptions
........................................................................................................... 109
Section 19.3: Iterating Over a Dictionary
................................................................................................................. 109
Section 19.4: Dictionary with default values
........................................................................................................... 110
Section 19.5: Merging dictionaries
...........................................................................................................................
111
Section 19.6: Accessing keys and values
................................................................................................................ 111
Section 19.7: Accessing values of a dictionary
....................................................................................................... 112
Section 19.8: Creating a dictionary
..........................................................................................................................
112
Section 19.9: Creating an ordered dictionary
......................................................................................................... 113
Section 19.10: Unpacking dictionaries using the ** operator
................................................................................. 113
Section 19.11: The trailing comma
............................................................................................................................
114
Section 19.12: The dict() constructor
........................................................................................................................
114
Section 19.13: Dictionaries Example
.........................................................................................................................
114
Section 19.14: All combinations of dictionary values
.............................................................................................. 115
Chapter 20: List
.................................................................................................................................................
117
Section 20.1: List methods and supported operators
............................................................................................ 117
Section 20.2: Accessing list values
..........................................................................................................................
122
Section 20.3: Checking if list is empty
..................................................................................................................... 123
Section 20.4: Iterating over a list
.............................................................................................................................
123
Section 20.5: Checking whether an item is in a list
................................................................................................ 124
Section 20.6: Any and All
..........................................................................................................................................
124
Section 20.7: Reversing list elements
......................................................................................................................
125
Section 20.8: Concatenate and Merge lists
............................................................................................................ 125
Section 20.9: Length of a list
....................................................................................................................................
126
Section 20.10: Remove duplicate values in list
....................................................................................................... 126
Section 20.11: Comparison of lists
............................................................................................................................
127
Section 20.12: Accessing values in nested list
........................................................................................................ 127
Section 20.13: Initializing a List to a Fixed Number of Elements
........................................................................... 128
Chapter 21: List comprehensions
......................................................................................................................
130
Section 21.1: List Comprehensions
...........................................................................................................................
130
Section 21.2: Conditional List Comprehensions
...................................................................................................... 132
Section 21.3: Avoid repetitive and expensive operations using conditional
clause ............................................ 134
Section 21.4: Dictionary Comprehensions
............................................................................................................... 135
Section 21.5: List Comprehensions with Nested Loops
.......................................................................................... 136
Section 21.6: Generator Expressions
........................................................................................................................
138
Section 21.7: Set Comprehensions
...........................................................................................................................
140
Section 21.8: Refactoring filter and map to list comprehensions
......................................................................... 140
Section 21.9: Comprehensions involving tuples
...................................................................................................... 141
Section 21.10: Counting Occurrences Using Comprehension
............................................................................... 142
Section 21.11: Changing Types in a List
.................................................................................................................... 142
Section 21.12: Nested List Comprehensions
............................................................................................................ 142
Section 21.13: Iterate two or more list simultaneously within list
comprehension .............................................. 143
Chapter 22: List slicing (selecting parts of lists)
....................................................................................... 144
Section 22.1: Using the third "step" argument
........................................................................................................ 144
Section 22.2: Selecting a sublist from a list
............................................................................................................ 144
Section 22.3: Reversing a list with slicing
................................................................................................................ 144
Section 22.4: Shifting a list using slicing
.................................................................................................................. 144
Chapter 23: groupby()
............................................................................................................................................
146
Section 23.1: Example 4
.............................................................................................................................................
146
Section 23.2: Example 2
............................................................................................................................................
146
Section 23.3: Example 3
............................................................................................................................................
147
Chapter 24: Linked lists
.........................................................................................................................................
149
Section 24.1: Single linked list example
................................................................................................................... 149
Chapter 25: Linked List Node
.............................................................................................................................
154
Section 25.1: Write a simple Linked List Node in python
....................................................................................... 154
Chapter 26: Filter
.................................................................................................................................................
155
Section 26.1: Basic use of filter
.................................................................................................................................
155
Section 26.2: Filter without function
........................................................................................................................
155
Section 26.3: Filter as short-circuit check
............................................................................................................... 156
Section 26.4: Complementary function: filterfalse, ifilterfalse
.............................................................................. 156
Chapter 27: Heapq
.................................................................................................................................................
158
Section 27.1: Largest and smallest items in a collection
....................................................................................... 158
Section 27.2: Smallest item in a collection
.............................................................................................................. 158
Chapter 28: Tuple
.................................................................................................................................................
160
Section 28.1: Tuple
.................................................................................................................................................
160
Section 28.2: Tuples are immutable
........................................................................................................................
161
Section 28.3: Packing and Unpacking Tuples
........................................................................................................ 161
Section 28.4: Built-in Tuple Functions
..................................................................................................................... 162
Section 28.5: Tuple Are Element-wise Hashable and Equatable
......................................................................... 163
Section 28.6: Indexing Tuples
...................................................................................................................................
164
Section 28.7: Reversing Elements
............................................................................................................................
164
Chapter 29: Basic Input and Output
............................................................................................................... 165
Section 29.1: Using the print function
......................................................................................................................
165
Section 29.2: Input from a File
.................................................................................................................................
165
Section 29.3: Read from stdin
..................................................................................................................................
167
Section 29.4: Using input() and raw_input()
.......................................................................................................... 167
Section 29.5: Function to prompt user for a number
............................................................................................ 167
Section 29.6: Printing a string without a newline at the end
................................................................................. 168
Chapter 30: Files & Folders I/O
.........................................................................................................................
171
Section 30.1: File modes
............................................................................................................................................
171
Section 30.2: Reading a file line-by-line
.................................................................................................................. 172
Section 30.3: Iterate files (recursively)
.................................................................................................................... 173
Section 30.4: Getting the full contents of a file
...................................................................................................... 173
Section 30.5: Writing to a file
...................................................................................................................................
174
Section 30.6: Check whether a file or path exists
.................................................................................................. 175
Section 30.7: Random File Access Using mmap
.................................................................................................... 176
Section 30.8: Replacing text in a file
.......................................................................................................................
176
Section 30.9: Checking if a file is empty
................................................................................................................. 176
Section 30.10: Read a file between a range of lines
.............................................................................................. 177
Section 30.11: Copy a directory tree
........................................................................................................................
177
Section 30.12: Copying contents of one file to a di☐erent file
.............................................................................. 177
Chapter 31: os.path
.................................................................................................................................................
178
Section 31.1: Join Paths
.............................................................................................................................................
178
Section 31.2: Path Component Manipulation
.......................................................................................................... 178
Section 31.3: Get the parent directory
..................................................................................................................... 178
Section 31.4: If the given path exists
........................................................................................................................
178
Section 31.5: check if the given path is a directory, file, symbolic link, mount
point etc .................................... 179
Section 31.6: Absolute Path from Relative Path
..................................................................................................... 179
Chapter 32: Iterables and Iterators
................................................................................................................ 180
Section 32.1: Iterator vs Iterable vs Generator
....................................................................................................... 180
Section 32.2: Extract values one by one
................................................................................................................. 181
Section 32.3: Iterating over entire iterable
............................................................................................................. 181
Section 32.4: Verify only one element in iterable
.................................................................................................. 181
Section 32.5: What can be iterable
..........................................................................................................................
182
Section 32.6: Iterator isn't reentrant!
.......................................................................................................................
182
Chapter 33: Functions
.............................................................................................................................................
183
Section 33.1: Defining and calling simple functions
............................................................................................... 183
Section 33.2: Defining a function with an arbitrary number of arguments
........................................................ 184
Section 33.3: Lambda (Inline/Anonymous) Functions
.......................................................................................... 187
Section 33.4: Defining a function with optional arguments
.................................................................................. 189
Section 33.5: Defining a function with optional mutable arguments
................................................................... 190
Section 33.6: Argument passing and mutability
.................................................................................................... 191
Section 33.7: Returning values from functions
....................................................................................................... 192
Section 33.8: Closure
................................................................................................................................................
192
Section 33.9: Forcing the use of named parameters
............................................................................................ 193
Section 33.10: Nested functions
...............................................................................................................................
194
Section 33.11: Recursion limit
....................................................................................................................................
194
Section 33.12: Recursive Lambda using assigned variable
................................................................................... 195
Section 33.13: Recursive functions
...........................................................................................................................
195
Section 33.14: Defining a function with arguments
................................................................................................ 196
Section 33.15: Iterable and dictionary unpacking
.................................................................................................. 196
Section 33.16: Defining a function with multiple arguments
................................................................................. 198
Chapter 34: Defining functions with list arguments
.............................................................................. 199
Section 34.1: Function and Call
.................................................................................................................................
199
Chapter 35: Functional Programming in Python
...................................................................................... 201
Section 35.1: Lambda Function
................................................................................................................................
201
Section 35.2: Map Function
......................................................................................................................................
201
Section 35.3: Reduce Function
.................................................................................................................................
201
Section 35.4: Filter Function
.....................................................................................................................................
201
Chapter 36: Partial functions
..............................................................................................................................
202
Section 36.1: Raise the power
...................................................................................................................................
202
Chapter 37: Decorators
.........................................................................................................................................
203
Section 37.1: Decorator function
..............................................................................................................................
203
Section 37.2: Decorator class
...................................................................................................................................
204
Section 37.3: Decorator with arguments (decorator factory)
.............................................................................. 205
Section 37.4: Making a decorator look like the decorated function
.................................................................... 207
Section 37.5: Using a decorator to time a function
............................................................................................... 207
Section 37.6: Create singleton class with a decorator
.......................................................................................... 208
Chapter 38: Classes
.................................................................................................................................................
209
Section 38.1: Introduction to classes
........................................................................................................................
209
Section 38.2: Bound, unbound, and static methods
.............................................................................................. 210
Section 38.3: Basic inheritance
................................................................................................................................
212
Section 38.4: Monkey Patching
................................................................................................................................
214
Section 38.5: New-style vs. old-style classes
.......................................................................................................... 214
Section 38.6: Class methods: alternate initializers
................................................................................................. 215
Section 38.7: Multiple Inheritance
............................................................................................................................
217
Section 38.8: Properties
............................................................................................................................................
219
Section 38.9: Default values for instance variables
............................................................................................... 220
Section 38.10: Class and instance variables
........................................................................................................... 221
Section 38.11: Class composition
..............................................................................................................................
222
Section 38.12: Listing All Class Members
................................................................................................................. 223
Section 38.13: Singleton class
...................................................................................................................................
224
Section 38.14: Descriptors and Dotted Lookups
.................................................................................................... 225
Chapter 39: Metaclasses
.......................................................................................................................................
226
Section 39.1: Basic Metaclasses
...............................................................................................................................
226
Section 39.2: Singletons using metaclasses
........................................................................................................... 227
Section 39.3: Using a metaclass
..............................................................................................................................
227
Section 39.4: Introduction to Metaclasses
.............................................................................................................. 227
Section 39.5: Custom functionality with metaclasses
........................................................................................... 228
Section 39.6: The default metaclass
.......................................................................................................................
229
Chapter 40: String Formatting
.........................................................................................................................
232
Section 40.1: Basics of String Formatting
............................................................................................................... 232
Section 40.2: Alignment and padding
..................................................................................................................... 233
Section 40.3: Format literals (f-string)
.................................................................................................................... 234
Section 40.4: Float formatting
.................................................................................................................................
234
Section 40.5: Named placeholders
.........................................................................................................................
235
Section 40.6: String formatting with datetime
....................................................................................................... 236
Section 40.7: Formatting Numerical Values
........................................................................................................... 236
Section 40.8: Nested formatting
..............................................................................................................................
237
Section 40.9: Format using Getitem and Getattr
................................................................................................... 237
Section 40.10: Padding and truncating strings, combined
.................................................................................... 237
Section 40.11: Custom formatting for a class
......................................................................................................... 238
Chapter 41: String Methods
................................................................................................................................
240
Section 41.1: Changing the capitalization of a string
............................................................................................. 240
Section 41.2: str.translate: Translating characters in a string
............................................................................... 241
Section 41.3: str.format and f-strings: Format values into a string
...................................................................... 242
Section 41.4: String module's useful constants
....................................................................................................... 243
Section 41.5: Stripping unwanted leading/trailing characters from a string
...................................................... 244
Section 41.6: Reversing a string
...............................................................................................................................
245
Section 41.7: Split a string based on a delimiter into a list of strings
................................................................... 245
Section 41.8: Replace all occurrences of one substring with another substring
................................................ 246
Section 41.9: Testing what a string is composed of
............................................................................................... 247
Section 41.10: String Contains
...................................................................................................................................
249
Section 41.11: Join a list of strings into one string
................................................................................................... 249
Section 41.12: Counting number of times a substring appears in a string
.......................................................... 250
Section 41.13: Case insensitive string comparisons
................................................................................................ 250
Section 41.14: Justify strings
.....................................................................................................................................
251
Section 41.15: Test the starting and ending characters of a string
...................................................................... 252
Section 41.16: Conversion between str or bytes data and unicode characters
.................................................. 253
Chapter 42: Using loops within functions
.................................................................................................... 255
Section 42.1: Return statement inside loop in a function
...................................................................................... 255
Chapter 43: Importing modules
........................................................................................................................
256
Section 43.1: Importing a module
............................................................................................................................
256
Section 43.2: The __all__ special variable
............................................................................................................ 257
Section 43.3: Import modules from an arbitrary filesystem location
.................................................................. 258
Section 43.4: Importing all names from a module
................................................................................................ 258
Section 43.5: Programmatic importing
................................................................................................................... 259
Section 43.6: PEP8 rules for Imports
.......................................................................................................................
259
Section 43.7: Importing specific names from a module
........................................................................................ 260
Section 43.8: Importing submodules
.......................................................................................................................
260
Section 43.9: Re-importing a module
......................................................................................................................
260
Section 43.10: __import__() function
..................................................................................................................... 261
Chapter 44: Di ☐ erence between Module and Package
...................................................................... 262
Section 44.1: Modules
................................................................................................................................................
262
Section 44.2: Packages
.............................................................................................................................................
262
Chapter 45: Math Module
....................................................................................................................................
264
Section 45.1: Rounding: round, floor, ceil, trunc
...................................................................................................... 264
Section 45.2: Trigonometry
......................................................................................................................................
265
Section 45.3: Pow for faster exponentiation
........................................................................................................... 266
Section 45.4: Infinity and NaN ("not a number")
................................................................................................... 266
Section 45.5: Logarithms
..........................................................................................................................................
269
Section 45.6: Constants
............................................................................................................................................
269
Section 45.7: Imaginary Numbers
...........................................................................................................................
270
Section 45.8: Copying signs
.....................................................................................................................................
270
Section 45.9: Complex numbers and the cmath module
...................................................................................... 270
Chapter 46: Complex math
.................................................................................................................................
273
Section 46.1: Advanced complex arithmetic
........................................................................................................... 273
Section 46.2: Basic complex arithmetic
.................................................................................................................. 274
Chapter 47: Collections module
.......................................................................................................................
275
Section 47.1: collections.Counter
..............................................................................................................................
275
Section 47.2: collections.OrderedDict
......................................................................................................................
276
Section 47.3: collections.defaultdict
.........................................................................................................................
277
Section 47.4: collections.namedtuple
......................................................................................................................
278
Section 47.5: collections.deque
................................................................................................................................
279
Section 47.6: collections.ChainMap
..........................................................................................................................
280
Chapter 48: Operator module
...........................................................................................................................
282
Section 48.1: Itemgetter
............................................................................................................................................
282
Section 48.2: Operators as alternative to an infix operator
................................................................................. 282
Section 48.3: Methodcaller
.......................................................................................................................................
282
Chapter 49: JSON Module
....................................................................................................................................
284
Section 49.1: Storing data in a file
............................................................................................................................
284
Section 49.2: Retrieving data from a file
................................................................................................................ 284
Section 49.3: Formatting JSON output
................................................................................................................... 284
Section 49.4: `load` vs `loads`, `dump` vs `dumps`
................................................................................................... 285
Section 49.5: Calling `json.tool` from the command line to pretty-print JSON
output ...................................... 286
Section 49.6: JSON encoding custom objects
........................................................................................................ 286
Section 49.7: Creating JSON from Python dict
...................................................................................................... 287
Section 49.8: Creating Python dict from JSON
...................................................................................................... 287
Chapter 50: Sqlite3 Module
.................................................................................................................................
289
Section 50.1: Sqlite3 - Not require separate server process
................................................................................. 289
Section 50.2: Getting the values from the database and Error handling
........................................................... 289
Chapter 51: The os Module
...................................................................................................................................
291
Section 51.1: makedirs - recursive directory creation
............................................................................................ 291
Section 51.2: Create a directory
...............................................................................................................................
292
Section 51.3: Get current directory
..........................................................................................................................
292
Section 51.4: Determine the name of the operating system
................................................................................ 292
Section 51.5: Remove a directory
............................................................................................................................
292
Section 51.6: Follow a symlink (POSIX)
.................................................................................................................... 292
Section 51.7: Change permissions on a file
............................................................................................................. 292
Chapter 52: The locale Module
..........................................................................................................................
293
Section 52.1: Currency Formatting US Dollars Using the locale Module
............................................................. 293
Chapter 53: Itertools Module
..............................................................................................................................
294
Section 53.1: Combinations method in Itertools Module
....................................................................................... 294
Section 53.2: itertools.dropwhile
..............................................................................................................................
294
Section 53.3: Zipping two iterators until they are both exhausted
...................................................................... 295
Section 53.4: Take a slice of a generator
............................................................................................................... 295
Section 53.5: Grouping items from an iterable object using a function
.............................................................. 296
Section 53.6: itertools.takewhile
...............................................................................................................................
297
Section 53.7: itertools.permutations
........................................................................................................................
297
Section 53.8: itertools.repeat
....................................................................................................................................
298
Section 53.9: Get an accumulated sum of numbers in an iterable
...................................................................... 298
Section 53.10: Cycle through elements in an iterator
............................................................................................ 298
Section 53.11: itertools.product
.................................................................................................................................
298
Section 53.12: itertools.count
....................................................................................................................................
299
Section 53.13: Chaining multiple iterators together
............................................................................................... 300
Chapter 54: Asyncio Module
...............................................................................................................................
301
Section 54.1: Coroutine and Delegation Syntax
..................................................................................................... 301
Section 54.2: Asynchronous Executors
................................................................................................................... 302
Section 54.3: Using UVLoop
.....................................................................................................................................
303
Section 54.4: Synchronization Primitive: Event
....................................................................................................... 303
Section 54.5: A Simple Websocket
..........................................................................................................................
304
Section 54.6: Common Misconception about asyncio
.......................................................................................... 304
Chapter 55: Random module
.............................................................................................................................
307
Section 55.1: Creating a random user password
................................................................................................... 307
Section 55.2: Create cryptographically secure random numbers
....................................................................... 307
Section 55.3: Random and sequences: shu☐e, choice and sample
.................................................................... 308
Section 55.4: Creating random integers and floats: randint, randrange,
random, and uniform ...................... 309
Section 55.5: Reproducible random numbers: Seed and State
............................................................................ 310
Section 55.6: Random Binary Decision
................................................................................................................... 311
Chapter 56: Functools Module
...........................................................................................................................
312
Section 56.1: partial
.................................................................................................................................................
312
Section 56.2: cmp_to_key
.......................................................................................................................................
312
Section 56.3: lru_cache
.............................................................................................................................................
312
Section 56.4: total_ordering
.....................................................................................................................................
313
Section 56.5: reduce
.................................................................................................................................................
314
Chapter 57: The dis module
................................................................................................................................
315
Section 57.1: What is Python bytecode?
................................................................................................................. 315
Section 57.2: Constants in the dis module
.............................................................................................................. 315
Section 57.3: Disassembling modules
..................................................................................................................... 315
Chapter 58: The base64 Module
.......................................................................................................................
317
Section 58.1: Encoding and Decoding Base64
....................................................................................................... 318
Section 58.2: Encoding and Decoding Base32
....................................................................................................... 319
Section 58.3: Encoding and Decoding Base16
........................................................................................................ 320
Section 58.4: Encoding and Decoding ASCII85
...................................................................................................... 320
Section 58.5: Encoding and Decoding Base85
....................................................................................................... 321
Chapter 59: Queue Module
..................................................................................................................................
322
Section 59.1: Simple example
...................................................................................................................................
322
Chapter 60: Deque Module
..................................................................................................................................
324
Section 60.1: Basic deque using
...............................................................................................................................
324
Section 60.2: Available methods in deque
.............................................................................................................. 324
Section 60.3: limit deque size
...................................................................................................................................
325
Section 60.4: Breadth First Search
..........................................................................................................................
325
Chapter 61: Webbrowser Module
......................................................................................................................
326
Section 61.1: Opening a URL with Default Browser
................................................................................................ 326
Section 61.2: Opening a URL with Di☐erent Browsers
........................................................................................... 327
Chapter 62: tkinter
.................................................................................................................................................
328
Section 62.1: Geometry Managers
...........................................................................................................................
328
Section 62.2: A minimal tkinter Application
............................................................................................................ 329
Chapter 63: pyautogui module
..........................................................................................................................
331
Section 63.1: Mouse Functions
..................................................................................................................................
331
Section 63.2: Keyboard Functions
...........................................................................................................................
331
Section 63.3: Screenshot And Image Recognition
................................................................................................. 331
Chapter 64: Indexing and Slicing
......................................................................................................................
332
Section 64.1: Basic Slicing
.........................................................................................................................................
332
Section 64.2: Reversing an object
...........................................................................................................................
333
Section 64.3: Slice assignment
.................................................................................................................................
333
Section 64.4: Making a shallow copy of an array
.................................................................................................. 333
Section 64.5: Indexing custom classes: __getitem__, __setitem__ and
__delitem__ ................................... 334
Section 64.6: Basic Indexing
.....................................................................................................................................
335
Chapter 65: Plotting with Matplotlib
.............................................................................................................. 337
Section 65.1: Plots with Common X-axis but di☐erent Y-axis : Using
twinx() ....................................................... 337
Section 65.2: Plots with common Y-axis and di☐erent X-axis using twiny()
....................................................... 338
Section 65.3: A Simple Plot in Matplotlib
................................................................................................................. 340
Section 65.4: Adding more features to a simple plot : axis labels, title, axis
ticks, grid, and legend ................ 341
Section 65.5: Making multiple plots in the same figure by superimposition
similar to MATLAB ...................... 342
Section 65.6: Making multiple Plots in the same figure using plot
superimposition with separate plot commands
.................................................................................................................................................
343
Chapter 66: graph-tool
..........................................................................................................................................
345
Section 66.1: PyDotPlus
.............................................................................................................................................
345
Section 66.2: PyGraphviz
..........................................................................................................................................
345
Chapter 67: Generators
.........................................................................................................................................
347
Section 67.1: Introduction
..........................................................................................................................................
347
Section 67.2: Infinite sequences
...............................................................................................................................
349
Section 67.3: Sending objects to a generator
........................................................................................................ 350
Section 67.4: Yielding all values from another iterable
......................................................................................... 351
Section 67.5: Iteration
...............................................................................................................................................
351
Section 67.6: The next() function
.............................................................................................................................
351
Section 67.7: Coroutines
...........................................................................................................................................
352
Section 67.8: Refactoring list-building code
........................................................................................................... 352
Section 67.9: Yield with recursion: recursively listing all files in a directory
........................................................ 353
Section 67.10: Generator expressions
......................................................................................................................
354
Section 67.11: Using a generator to find Fibonacci Numbers
............................................................................... 354
Section 67.12: Searching
...........................................................................................................................................
354
Section 67.13: Iterating over generators in parallel
............................................................................................... 355
Chapter 68: Reduce
.................................................................................................................................................
356
Section 68.1: Overview
..............................................................................................................................................
356
Section 68.2: Using reduce
.......................................................................................................................................
356
Section 68.3: Cumulative product
............................................................................................................................
357
Section 68.4: Non short-circuit variant of any/all
................................................................................................. 357
Chapter 69: Map Function
....................................................................................................................................
358
Section 69.1: Basic use of map, itertools.imap and future_builtins.map
............................................................. 358
results
.................................................................................................................................................
750
Section 186.1: Simple transform
...............................................................................................................................
750
Section 186.2: Multiple results per group
................................................................................................................ 751
Chapter 187: Similarities in syntax, Di ☐ erences in meaning: Python vs.
JavaScript ............. 752
Section 187.1: `in` with lists
.........................................................................................................................................
752
Chapter 188: Call Python from C#
................................................................................................................... 753
Section 188.1: Python script to be called by C# application
.................................................................................. 753
Section 188.2: C# code calling Python script
.......................................................................................................... 753
Chapter 189: ctypes
................................................................................................................................................
755
Section 189.1: ctypes arrays
.....................................................................................................................................
755
Section 189.2: Wrapping functions for ctypes
........................................................................................................ 755
Section 189.3: Basic usage
........................................................................................................................................
756
Section 189.4: Common pitfalls
................................................................................................................................
756
Section 189.5: Basic ctypes object
...........................................................................................................................
757
Section 189.6: Complex usage
..................................................................................................................................
758
Chapter 190: Writing extensions
........................................................................................................................
760
Section 190.1: Hello World with C Extension
............................................................................................................ 760
Section 190.2: C Extension Using c++ and Boost
.................................................................................................... 760
Section 190.3: Passing an open file to C Extensions
.............................................................................................. 762
Chapter 191: Python Lex-Yacc
.............................................................................................................................
763
Section 191.1: Getting Started with PLY
.................................................................................................................... 763
Section 191.2: The "Hello, World!" of PLY - A Simple Calculator
............................................................................ 763
Section 191.3: Part 1: Tokenizing Input with Lex
....................................................................................................... 765
Section 191.4: Part 2: Parsing Tokenized Input with Yacc
...................................................................................... 768
You can download and install either version of Python here . See Python 3
vs. Python 2 for a comparison between them. In addition, some third-parties
offer re-packaged versions of Python that add commonly used libraries and
other features to ease setup for common use cases, such as math, data
analysis or scientific use. See the list at the official site .
To confirm that Python was installed correctly, you can verify that by
running the following command in your favorite terminal (If you are using
Windows OS, you need to add path of python to the environment variable
before using it in command prompt):
You can use the Python 3 print function in Python 2 with the following
import statement:
from __future__ import print_function
Python 2 has a number of functionalities that can be optionally imported from
Python 3 using the __future__ module, as discussed here.
Python 2.xVersion ≤ 2.7
If using Python 2, you may also type the line below. Note that this is not
valid in Python 3 and thus not recommended because it reduces cross-version
code compatibility.
print 'Hello, World'
In your terminal, navigate to the directory containing the file hello.py.
Type python hello.py, then hit the Enter key.
$ python hello.py Hello, World
You should see Hello, World printed to the console.
You can also substitute hello.py with the path to your file. For example, if
you have the file in your home directory and your user is "user" on Linux,
you can type python /home/user /hello.py.
Launch an interactive Python shell
By executing (running) the python command in your terminal, you are
presented with an interactive Python shell. This is also known as the Python
Interpreter or a REPL (for 'Read Evaluate Print Loop').
$ python
Python 2.7.12 (default, Jun 28 2016 , 08 :46 :01 )
[GCC 6.1.1 20160602 ] on linux
Type "help" , "copyright" , "credits" or "license" for more information. >>> print
'Hello, World'
Hello, World
>>>
If you want to run Python 3 from your terminal, execute the command
python3.
$ python3
Python 3.6.0 (default, Jan 13 2017 , 00 :00 :00 )
[GCC 6.1.1 20160602 ] on linux
Type "help" , "copyright" , "credits" or "license" for more information. >>> print
('Hello, World' )
Hello, World
>>>
Alternatively, start the interactive prompt and load file with python -i < file
.py> .
In command line, run:
Examples:
Disclaimer: documentation author(s) are not affiliated with any resources
listed below.
Shells - So far, we have discussed different ways to run code using Python's
native interactive shell. Shells use Python's interpretive power for
experimenting with code real-time. Alternative shells include IDLE - a pre-
bundled GUI, IPython - known for extending the interactive experience, etc.
Programs - For long-term storage you can save content to .py files and
edit/execute them as scripts or programs with external tools e.g. shell, IDEs
(such as PyCharm ), Jupyter notebooks , etc. Intermediate users may use
these tools; however, the methods discussed here are sufficient for getting
started.
Python tutor allows you to step through Python code so you can visualize
how the program will flow, and helps you to understand where your program
went wrong.
PEP8 defines guidelines for formatting Python code. Formatting code well is
important so you can quickly read what the code does.
# Integer
a=2
print (a)
# Output: 2
# Integer
b = 9223372036854775807
print (b)
# Output: 9223372036854775807
# Floating point
pi = 3.14
print (pi)
# Output: 3.14
# String
c = 'A'
print (c)
# Output: A
# String
name = 'John Doe'
print (name)
# Output: John Doe
# Boolean
q = True
print (q)
# Output: True
Variable assignment works from left to right. So the following will give you
an syntax error.
0=x
=> Output: SyntaxError : can't assign to literal
You can not use python's keywords as a valid variable name. You can see the
list of keyword by:
import keyword
print (keyword .kwlist)
Rules for variable naming:
1. Variables names must start with a letter or an underscore.
x = True # valid _y = True # valid
9x = False # starts with numeral => SyntaxError : invalid syntax
$y = False # starts with symbol => SyntaxError : invalid syntax
2. The remainder of your variable name may consist of letters, numbers and
underscores.
has_0_in_it = "Still Valid"
3. Names are case sensitive.
x=9
y = X*5
=> NameError : name 'X' is not defined
Even though there's no need to specify a data type when declaring a variable
in Python, while allocating the necessary area in memory for the variable, the
Python interpreter automatically picks the most suitable built-in type for it:
a=2
print (type (a))
# Output: <type 'int'>
pi = 3.14
print (type (pi))
# Output: <type 'float'>
c = 'A'
print (type (c))
# Output: <type 'str'>
q = True
print (type (q))
# Output: <type 'bool'>
x = None
print (type (x))
# Output: <type 'NoneType'>
Now you know the basics of assignment, let's get this subtlety about
assignment in python out of the way.
When you use = to do an assignment operation, what's on the left of = is a
name for the object on the right. Finally, what = does is assign the reference
of the object on the right to the name on the left.
That is:
a_name = an_object # "a_name" is now a name for the reference to the object
"an_object"
You can assign multiple values to multiple variables in one line. Note that
there must be the same number of arguments on the right and left sides of the
= operator:
a , b, c = 1 , 2
=> Traceback (most recent call last):
=> File "name.py" , line N, in < module> => a, b, c = 1 , 2
=> ValueError : need more than 2 values to unpack
a,b=1,2,3
=> Traceback (most recent call last): => File "name.py" , line N, in < module>
=> a, b = 1 , 2 , 3
=> ValueError : too many values to unpack
a , b, _ = 1 , 2 , 3 print (a, b)
# Output: 1, 2
Note that the number of _ and number of remaining values must be equal.
Otherwise 'too many values to unpack error' is thrown as above:
a , b, _ = 1 , 2 , 3 , 4
=> Traceback (most recent call last):
=> File "name.py" , line N, in < module>
=> a, b, _ = 1 , 2 , 3 , 4
=> ValueError : too many values to unpack (expected 3 )
When using such cascading assignment, it is important to note that all three
variables a, b and c refer to the same object in memory, an int object with the
value of 1. In other words, a, b and c are three different names given to the
same int object. Assigning a different object to one of them afterwards
doesn't change the others, just as expected:
a = b = c = 1 # all three names a, b and c refer to same int object with value 1
print (a, b, c)
# Output: 1 1 1
b = 2 # b now refers to another int object, one with a value of 2 print (a, b, c)
# Output: 1 2 1 # so output is as expected.
The above is also true for mutable types (like list , dict , etc.) just as it is true
for immutable types (like int , string , tuple , etc.):
So far so good. Things are a bit different when it comes to modifying the
object (in contrast to assigning the name to a different object, which we did
above) when the cascading assignment is used for mutable types. Take a look
below, and you will see it first hand:
x = y = [7 , 8 , 9 ] # x and y are two different names for the same list object just
created, [7, 8, 9]
x[0 ] = 13 # we are updating the value of the list [7, 8, 9] through one of its
names, x in this case
print (y) # printing the value of the list using its other name
# Output: [13, 8, 9] # hence, naturally the change is reflected
Nested lists are also valid in python. This means that a list can contain
another list as an element.
Lastly, variables in Python do not have to stay the same type as which they
were first defined -- you can simply use = to assign a new value to a variable,
even if that value is of a different type.
a=2
print (a)
# Output: 2
If this bothers you, think about the fact that what's on the left of = is just a
name for an object. First you call the int object with value 2 a, then you
change your mind and decide to give the name a to a string object, having
value 'New value'. Simple, right?
Python uses the colon symbol ( :) and indentation for showing where blocks
of code begin and end (If you come from another language, do not confuse
this with somehow being related to the ternary operator ). That is, blocks in
Python, such as functions, loops, if clauses and other constructs, have no
ending identifiers. All blocks start with a colon and then contain the indented
lines below it.
For example:
Blocks that contain exactly one single-line statement may be put on the same
line, though this form is generally not considered good style:
if a > b: print (a) else : print (b)
Attempting to do this with more than a single statement will not work:
if x > y: y = x
print (y) # IndentationError: unexpected indent
if x > y: while y != z: y = 1 # SyntaxError: invalid syntax
An empty block causes an IndentationError. Use pass (a command that does
nothing) when you have a block with no content:
def will_be_implemented_later(): pass
Spaces vs. Tabs
In short: always use 4 spaces for indentation.
Using tabs exclusively is possible but PEP 8 , the style guide for Python
code, states that spaces are preferred.
Python 3.xVersion ≥ 3.0
Python 3 disallows mixing the use of tabs and spaces for indentation. In such
case a compile-time error is generated: Inconsistent use of tabs and spaces in
indentation and the program will not run.
Python 2.xVersion ≤ 2.7
Citing PEP 8 :
When invoking the Python 2 command line interpreter with the -t option, it
issues warnings about code that illegally mixes tabs and spaces. When using -
tt these warnings become errors. These options are highly recommended!
Python source code written with a mix of tabs and spaces, or with non-
standard number of indentation spaces can be made pep8-conformant using
autopep8 . (A less powerful alternative comes with most Python installations:
reindent.py )
a=2
b = 100
c = 123456789
d = 38563846326424324
a = 2.0
b = 100. e0
c = 123456789. e1
str : a byte string . The type of 'hello' bytes : synonym for str
unicode : a unicode string . The type of u'hello'
a = (1 , 2 , 3 )
b = ('a' , 1 , 'python' , (1 , 2 ))
b[2 ] = 'something else' # returns a TypeError
Supports indexing; immutable; hashable if all its members are hashable list :
An ordered collection of n values (n >= 0 )
a = [1 , 2 , 3 ]
b = ['a' , 1 , 'python' , (1 , 2 ), [1 , 2 ]] b[2 ] = 'something else' # allowed
An object is hashable if it has a hash value which never changes during its
lifetime (it needs a __hash__ () method), and can be compared to other
objects (it needs an __eq__ () method). Hashable objects which compare
equality must have the same hash value.
Built-in constants
In conjunction with the built-in datatypes there are a small number of built-in
constants in the built-in namespace:
a = '123.456'
b = float (a)
c = int (a) # ValueError: invalid literal for int() with base 10: '123.456' d = int
(b) # 123
a = 'hello'
list (a) # ['h', 'e', 'l', 'l', 'o'] set (a) # {'o', 'e', 'l', 'h'} tuple (a) # ('h', 'e', 'l', 'l', 'o')
def bar():
x = (1 , 2 )
g(x)
x == (1 , 2 ) # Will always be True, since no function can change the object (1,
2)
Note that variables themselves are mutable, so we can reassign the variable
x, but this does not change the object that x had previously pointed to. It only
made x point to a new object.
Data types whose instances are mutable are called mutable data types , and
similarly for immutable objects and datatypes.
Examples of immutable Data Types:
bytearray list
set
dict
The list type is probably the most commonly used collection type in Python.
Despite its name, a list is more like an array in other languages, mostly
JavaScript. In Python, a list is merely an ordered collection of valid Python
values. A list can be created by enclosing values, separated by commas, in
square brackets:
int_list = [1 , 2 , 3 ]
string_list = ['abc' , 'defghi' ]
A list can be empty:
empty_list = []
The elements of a list are not restricted to a single data type, which makes
sense given that Python is a dynamic language:
mixed_list = [1 , 'abc' , True , 2.34 , None ]
A list can contain another list as its element:
nested_list = [['a' , 'b' , 'c' ], [1 , 2 , 3 ]]
The elements of a list can be accessed via an index , or numeric
representation of their position. Lists in Python are zero-indexed meaning that
the first element in the list is at index 0, the second element is at index 1 and
so on:
Indices can also be negative which means counting from the end of the list
(-1 being the index of the last element). So, using the list from the above
example:
print (names[1 ]) # Eric print (names[4 ]) # Bob
Lists are mutable, so you can change the values in a list:
names[ 0 ] = 'Ann'
print (names)
# Outputs ['Ann', 'Bob', 'Craig', 'Diana', 'Eric']
names.insert( 1 , "Nikki" )
print (names)
# Outputs ['Alice', 'Nikki', 'Bob', 'Craig', 'Diana', 'Eric', 'Sia']
a = [1 , 1 , 1 , 2 , 3 , 4 ] a.count(1 )
3
a.reverse()
[4 , 3 , 2 , 1 , 1 , 1 ] # or
a[::1 ]
[4 , 3 , 2 , 1 , 1 , 1 ]
Remove and return item at index (defaults to the last item) with
L.pop([index]), returns the item
names.pop() # Outputs 'Sia'
You can iterate over the list elements like below:
for element in my_list: print (element)
Tuples
state_capitals = {
'Arkansas' : 'Little Rock' , 'Colorado' : 'Denver' , 'California' : 'Sacramento' ,
'Georgia' : 'Atlanta'
}
To get a value, refer to it by its key:
ca_capital = state_capitals['California' ]
You can also get all of the keys in a dictionary and then iterate over them:
for k in state_capitals.keys():
print ('{} is the capital of {}' .format(state_capitals[k], k))
Dictionaries strongly resemble JSON syntax. The native json module in the
Python standard library can be used to convert between JSON and
dictionaries.
set
A defaultdict is a dictionary with a default value for keys, so that keys for
which no value has been explicitly defined can be accessed without errors.
defaultdict is especially useful when the values in the dictionary are
collections (lists, dicts, etc) in the sense that it does not need to be initialized
every time when a new key is used. A defaultdict will never raise a KeyError.
Any key that does not exist gets the default value returned.
>>> state_capitals = {
'Arkansas' : 'Little Rock' , 'Colorado' : 'Denver' , 'California' : 'Sacramento' ,
'Georgia' : 'Atlanta'
}
If we try to access a non-existent key, python returns us an error as follows
>>> state_capitals['Alabama' ] Traceback (most recent call last):
File "<ipython-input-61-236329695e6f>" , line 1 , in < module>
state_capitals['Alabama' ]
KeyError : 'Alabama'
Let us try with a defaultdict. It can be found in the collections module.
>>> from collections import defaultdict
>>> state_capitals = defaultdict(lambda : 'Boston' )
What we did here is to set a default value (Boston ) in case the give key does
not exist. Now populate the dict as before:
If we try to access the dict with a non-existent key, python will return us the
default value i.e. Boston
>>> state_capitals['Alabama' ] 'Boston'
and returns the created values for existing key just like a normal dictionary
>>> state_capitals['Arkansas' ] 'Little Rock'
In IDLE, hit F5 or run Python Shell to launch an interpreter. Using IDLE can
be a better learning experience for new users because code is interpreted as
the user writes.
Note that there are lots of alternatives, see for example this discussion or this
list .
Troubleshooting
Windows
You can also use the Python Launcher for Windows, which is available
through the installer and comes by default. It allows you to select the version
of Python to run by using py -[x.y] instead of python[x.y]. You can use the
latest version of Python 2 by running scripts with py 2 and the latest version
of Python 3 by running scripts with py 3 .
Debian/Ubuntu/MacOS
This section assumes that the location of the python executable has been
added to the PATH environment variable.
If you're on Debian/Ubuntu/MacOS, open the terminal and type python for
Python 2.x or python3 for Python 3.x.
Type which python to see which Python interpreter will be used.
Arch Linux
The default Python on Arch Linux (and descendants) is Python 3, so use
python or python3 for Python 3.x and python2 for Python 2.x.
Other systems
Python 3 is sometimes bound to python instead of python3. To use Python 2
on these systems where it is installed, you can use python2.
Security Remark Do not use input () in Python2 - the entered text will be
evaluated as if it were a Python expression (equivalent to eval (input ()) in
Python3), which might easily become a vulnerability. See this article for
further information on the risks of using this function.
name = input ("What is your name? " ) # Out: What is your name? Bob print
(name)
# Out: Bob
Note that the input is always of type str , which is important if you want the
user to enter numbers. Therefore, you need to convert the str before trying to
use it as a number:
NB: It's recommended to use try /except blocks to catch exceptions when
dealing with user inputs. For instance, if your code wants to cast a raw_input
into an int , and what the user writes is uncastable, it raises a ValueError .
Section 1.8: Built in Modules and Functions
To check the built in function in python we can use dir (). If called without an
argument, return the names in the current scope. Else, return an alphabetized
list of names comprising (some of) the attribute of the given object, and of
attributes reachable from it.
def sayHello():
"""This is the function docstring.""" return 'Hello World'
For any user defined type, its attributes, its class's attributes, and recursively
the attributes of its class's base classes can be retrieved using dir()
>>> class MyClassObject(object ):
... pass
...
>>> dir (MyClassObject)
['__class__' , '__delattr__' , '__dict__' , '__doc__' , '__format__' , '__getattribute__'
'__hash__' , '__init__' , '__module__' , '__new__' , '__reduce__' , '__reduce_ex__'
'__repr__' , '__setattr__' , '__sizeof__' , '__str__' , '__subclasshook__' ,
'__weakref__' ]
Any data type can be simply converted to string using a builtin function
called str . This function is called by default when a data type is passed to
print
>>> str (123 ) # "123"
For modules that you have made, they will need to be in the same directory
as the file that you are importing them into. (However, you can also put them
into the Python lib directory with the pre-included modules, but should be
avoided if possible.)
$ python
>>> import hello
>>> hello.say_hello()
=> "Hello!"
Modules can be imported by other modules.
# greet.py
import hello
hello.say_hello()
Specific functions of a module can be imported.
# greet.py
from hello import say_hello say_hello()
# greet.py
import hello as ai ai.say_hello()
# run_hello.py
if __name__ == '__main__' : from hello import say_hello
say_hello()
Run it!
$ python run_hello.py => "Hello!"
If the module is inside a directory and needs to be detected by python, the
directory should contain a file named __init__ .py.
Python 3 will install the Python launcher which can be used to launch Python
2.x and Python 3.x interchangeably from the command-line:
P:\ > py 3
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017 , 17 :54 :52 ) [MSC v.1900 32 bit
(Intel)] on win32 Type "help" , "copyright" , "credits" or "license" for more
information.
>>>
C:\ > py 2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016 , 20 :42 :59 ) [MSC
v.1500 32 Intel)] on win32 Type "help" , "copyright" , "credits" or "license" for
more information.
>>>
To use the corresponding version of pip for a specific Python version, use:
C:\> py 3 -m pip -V
pip 9.0.1 from C:\Python36\lib\site-packages (python 3.6 )
C:\> py 2 -m pip -V
pip 9.0.1 from C:\Python27\lib\site-packages (python 2.7 )
Linux
The latest versions of CentOS, Fedora, Red Hat Enterprise (RHEL) and
Ubuntu come with Python 2.7.
To install Python 2.7 on linux manually, just do the following in terminal:
Also add the path of new python in PATH environment variable. If new
python is in /root/python2.7 .X then run export PATH =
$PATH:/root/python2.7 .X
Now to check if Python installation is valid write in terminal:
python --version
Ubuntu (From Source)
If you need Python 3.6 you can install it from source as shown below
(Ubuntu 16.10 and 17.04 have 3.6 version in the universal repository). Below
steps have to be followed for Ubuntu 16.04 and lower versions:
macOS
As we speak, macOS comes installed with Python 2.7.10, but this version is
outdated and slightly modified from the regular Python.
The version of Python that ships with OS X is great for learning but it ’s not
good for development. The version shipped with OS X may be out of date
from the official current Python release, which is considered the stable
production version. (source )
Install Homebrew :
/ usr/ bin/ ruby - e "$(curl -fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install Python 2.7:
brew install python For Python 3.x, use the command brew install python3
instead.
For many types, this function makes an attempt to return a string that would
yield an object with the same value when passed to eval (). Otherwise, the
representation is a string enclosed in angle brackets that contains the name of
the type of the object along with additional information. This often includes
the name and address of the object.
str()
For strings, this returns the string itself. The difference between this and repr
(object ) is that str (object ) does not always attempt to return a string that is
acceptable to eval (). Rather, its goal is to return a printable or 'human
readable' string. If no argument is given, this returns the empty string, ''.
Example 1:
s = """w'o"w"""
repr (s) # Output: '\'w\\\'o"w\'' str (s) # Output: 'w\'o"w'
eval (str (s)) == s # Gives a SyntaxError eval (repr (s)) == s # Output: True
Example 2:
import datetime
today = datetime .datetime .now()
str (today) # Output: '2016-09-15 06:58:46.915000'
repr (today) # Output: 'datetime.datetime(2016, 9, 15, 6, 58, 46, 915000)'
When writing a class, you can override these methods to do whatever you
want:
class Represent(object ):
def __init__ (self , x, y): self .x, self .y = x, y
def __repr__ (self ):
return "Represent(x={},y= \" {} \" )" .format(self .x, self .y)
def __str__ (self ):
return "Representing x as {} and y as {}" .format(self .x, self .y)
Using the above class we can see the results:
r = Represent(1 , "Hopper" )
print (r) # prints __str__
print (r.__repr__ ) # prints __repr__: '<bound method Represent.__repr__
of Represent(x=1,y="Hopper")>'
rep = r.__repr__ () # sets the execution of __repr__ to a new variable print
(rep) # prints 'Represent(x=1,y="Hopper")'
r2 = eval (rep) # evaluates rep
print (r2) # prints __str__ from new object
print (r2 == r) # prints 'False' because they are different objects
pip is your friend when you need to install any package from the plethora of
choices available at the python package index (PyPI). pip is already installed
if you're using Python 2 >= 2.7.9 or Python 3 >= 3.4 downloaded from
python.org. For computers running Linux or another *nix with a native
package manager, pip must often be manually installed.
On instances with both Python 2 and Python 3 installed, pip often refers to
Python 2 and pip3 to Python 3. Using pip will only install packages for
Python 2 and pip3 will only install packages for Python 3.
Finding / installing a package
Searching for a package is as simple as typing
$ pip search < query>
# Searches for packages whose name or summary contains <query>
Installing a package is as simple as typing (in a terminal / command-prompt,
not in the Python interpreter)
$ pip install [package_name] # latest version of the package
$ pip install [package_name]== x.x.x # specific version of the package
$ pip install '[package_name]>=x.x.x' # minimum version of the package
where x.x.x is the version number of the package you want to install.
When your server is behind proxy, you can install package by using below
command:
$ pip --proxy http://< server address> :< port> install Upgrading installed
packages
When new versions of installed packages appear they are not automatically
installed to your system. To get an overview of which of your installed
packages have become outdated, run:
$ pip list --outdated
To upgrade a specific package use
$ pip install [package_name] --upgrade
Updating all outdated packages is not a standard functionality of pip.
Upgrading pip
You can upgrade your existing pip installation by using the following
commands
On Linux or macOS X:
$ pip install -U pip
You may need to use sudo with pip on some Linux Systems
On Windows:
py -m pip install -U pip
or
python -m pip install -U pip For more information regarding pip do read here
.
class _Helper(builtins.object)
| Define the builtin 'help'.
|
| This is a wrapper around pydoc.help that provides a helpful message | when
'help' is typed at the Python interactive prompt.
|
| Calling help() at the Python prompt starts an interactive help session. |
Calling help(thing) prints help for the python object 'thing'. |
| Methods defined here:
|
| __call__(self, *args, **kwds)
|
| __repr__(self)
|
| ---------------------------------------------------------------------| Data descriptors
defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
Sets are unordered collections of unique objects, there are two types of set:
1. Sets - They are mutable and new elements can be added once sets are
defined
2. Frozen Sets - They are immutable and new elements cannot added after its
defined.
b = frozenset ('asdfagsa' )
print (b)
> frozenset ({'f' , 'g' , 'd' , 'a' , 's' })
cities = frozenset (["Frankfurt" , "Basel" , "Freiburg" ]) print (cities)
> frozenset ({'Frankfurt' , 'Basel' , 'Freiburg' })
list = [123 , 'abcd' , 10.2 , 'd' ] #can be an array of any data type or single data
type. list1 = ['hello' , 'world' ]
print (list ) #will output whole list. [123,'abcd',10.2,'d']
print (list [0 :2 ]) #will output first two element of list. [123,'abcd'] print
(list1 * 2 ) #will gave list1 two times. ['hello','world','hello','world'] print (list
+ list1) #will gave concatenation of both the lists.
[123,'abcd',10.2,'d','hello','world']
#will output only value with 'name' key. 'red' #will output list of values in dic.
['red',10] #will output list of keys. ['name','age']
Lists are enclosed in brackets [ ] and their elements and size can be changed,
while tuples are enclosed in parentheses ( ) and cannot be updated. Tuples are
immutable.
Chapter 3: Indentation
Section 3.1: Simple example
class ExampleClass:
#Every function belonging to a class must be indented equally
def __init__ (self ):
name = "example"
def someFunction(self , a):
#Notice everything belonging to a function must be indented
if a > 5 :
return True
else :
return False
#If a function is not indented to the same level it will not be considers as part
of the parent class def separateFunction(b):
for i in b:
#Loops are also indented and nested conditions start a new indentation
if i == 1 :
return True
return False
separateFunction([2 , 3 , 5 , 6 , 1 ])
Spaces or Tabs?
The recommended indentation is 4 spaces but tabs or spaces can be used so
long as they are consistent. Do not mix tabs and spaces in Python as this will
cause an error in Python 3 and can causes errors in Python 2 .
The lexical analyzer uses a stack to store indentation levels. At the beginning,
the stack contains just the value 0, which is the leftmost position. Whenever a
nested block begins, the new indentation level is pushed on the stack, and an
"INDENT" token is inserted into the token stream which is passed to the
parser. There can never be more than one "INDENT" token in a row
(IndentationError).
<if> <foo> <:> [0] <INDENT> <if> <bar> <:> [0, 4] <INDENT> <x> <= >
<42 > [0, 4, 8] <DEDENT> <DEDENT> <else> <:> [0] <INDENT>
<print> <foo> [0, 2] <DEDENT>
The parser than handles the "INDENT" and "DEDENT" tokens as block
delimiters.
def isEven(a):
if a%2 == 0 :
return True
#this next line should be even with the if return False
print isEven(7 )
Comments are used to explain code when the basic code itself isn't clear.
Python ignores comments, and so will not execute code in there, or raise
syntax errors for plain English sentences.
Single-line comments begin with the hash character (#) and are terminated by
the end of line.
Single line comment:
# This is a single line comment in Python
Inline comment:
print ("Hello World" ) # This line prints "Hello World"
Comments spanning multiple lines have """ or ''' on either end. This is the
same as a multiline string, but they can be used as comments:
"""
This type of comment spans multiple lines.
These are mostly used for documentation of functions, classes and modules.
"""
def func():
"""This is a function that does nothing at all"""
return
class Greeter:
"""An object used to greet people. It contains multiple greeting functions for
several languages and times of the day.
"""
The value of the docstring can be accessed within the program and is - for
example - used by the help command.
Syntax conventions PEP 257
PEP 257 defines a syntax standard for docstring comments. It basically
allows two types:
One-line Docstrings:
According to PEP 257, they should be used with short and simple functions.
Everything is placed in one line, e.g:
def hello():
"""Say hello to your friends.""" print ("Hello my friends!" )
The docstring shall end with a period, the verb should be in the imperative
form.
Multi-line Docstrings:
Multi-line docstring should be used for longer, more complex functions,
modules or classes.
def hello(name, language= "en" ): """Say hello to a person.
Arguments:
name: the name of the person
language: the language in which the person should be greeted """
print (greeting[language]+" " +name)
They start with a short summary (equivalent to the content of a one-line
docstring) which can be on the same line as the quotation marks or on the
next line, give additional detail and list parameters and return values.
Note PEP 257 defines what information should be given within a docstring, it
doesn't define in which format it should be given. This was the reason for
other parties and documentation parsing tools to specify their own standards
for documentation, some of which are listed below and in this question .
Sphinx
Google has published Google Python Style Guide which defines coding
conventions for Python, including documentation comments. In comparison
to the Sphinx/reST many people say that documentation according to
Google's guidelines is better human-readable.
Args:
name: the name of the person as string language: the language code string
Returns:
A number.
"""
Python 3.2+ has support for %z format when parsing a string into a datetime
object.
UTC offset in the form +HHMM or -HHMM (empty string if the object is
naive).
For other versions of Python, you can use an external library such as dateutil ,
which makes parsing a string with timezone into a datetime object is quick.
import dateutil.parser
dt = dateutil.parser .parse("2016-04-15T08:27:18-0500" )
The dt variable is now a datetime object with the following value: datetime
.datetime (2016 , 4 , 15 , 8 , 27 , 18 , tzinfo= tzoffset(None , 18000 ))
Section 5.2: Constructing timezone-aware datetimes
By default all datetime objects are naive. To make them timezone-aware, you
must attach a tzinfo object, which provides the UTC offset and timezone
abbreviation as a function of date and time.
Fixed Offset Time Zones
For time zones that are a fixed offset from UTC, in Python 3.2+, the datetime
module provides the timezone class, a concrete implementation of tzinfo,
which takes a timedelta and an (optional) name parameter:
Python 3.xVersion ≥ 3.2
from datetime import datetime , timedelta, timezone
JST = timezone(timedelta(hours= +9 ))
print (dt.tzname())
# UTC+09:00
For Python versions before 3.2, it is necessary to use a third party library,
such as dateutil . dateutil provides an equivalent class, tzoffset, which (as of
version 2.5.3) takes arguments of the form dateutil.tz.tzoffset(tzname, offset),
where offset is specified in seconds:
In addition to static time zones, dateutil provides time zone classes that use
daylight savings time (see the documentation for the tz module ). You can
use the tz.gettz() method to get a time zone object, which can then be passed
directly to the datetime constructor:
All edge cases are handled properly when using pytz, but pytz time zones
should not be directly attached to time zones through the constructor. Instead,
a pytz time zone should be attached using the time zone's localize method:
print (delta.days) # 60
print (delta.seconds) # 40826
# Date object
today = datetime .date.today()
new_year = datetime .date(2017 , 01 , 01 ) #datetime.date(2017, 1, 1)
# Time object
noon = datetime .time (12 , 0 , 0 ) #datetime.time(12, 0)
# Current datetime
now = datetime .datetime .now()
# Datetime object
millenium_turn = datetime .datetime (2000 , 1 , 1 , 0 , 0 , 0 )
#datetime.datetime(2000, 1, 1, 0, 0)
Arithmetic operations for these objects are only supported within same
datatype and performing simple arithmetic with instances of different types
will result in a TypeError.
# Do this instead
print ('Time since the millenium at midnight: ' ,
datetime .datetime (today.year, today.month, today.day) - millenium_turn) #
Or this
print ('Time since the millenium at noon: ' ,
datetime .datetime .combine(today, noon) - millenium_turn)
Today: 2016-04-15
Yesterday: 2016-04-14
Tomorrow: 2016-04-16
Difference between tomorrow and yesterday: 2 days, 0:00:00
import time
from datetime import datetime
seconds_since_epoch= time .time () #1469182681.709
But these 2 forms need a different format for strptime. Furthermore, strptime'
does not support at all parsing minute timezones that have a :in it, thus2016-
07-22 09:25:59+0300can be parsed, but the standard format2016-07-22
09:25:59+03:00` cannot.
There is a single-file library called iso8601 which properly parses ISO 8601
timestamps and only them.
It supports fractions and timezones, and the T separator all with a single
function:
import iso8601
iso8601.parse_date('2016-07-22 09:25:59' )
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22 09:25:59+03:00' )
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>)
iso8601.parse_date('2016-07-22 09:25:59Z' )
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22T09:25:59.000111+03:00' )
# datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00'
...>)
Section 5.11: Parsing a string with a short time zone name into
a timezone aware datetime object
Using the dateutil library as in the previous example on parsing timezone-
aware timestamps, it is also possible to parse timestamps with a specified
"short" time zone name.
For dates formatted with short time zone names or abbreviations, which are
generally ambiguous (e.g. CST, which could be Central Standard Time,
China Standard Time, Cuba Standard Time, etc - more can be found here ) or
not necessarily available in a standard database, it is necessary to specify a
mapping between time zone abbreviation and tzinfo object.
us_tzinfos = {'CST' : CT, 'CDT' : CT, 'EST' : ET, 'EDT' : ET, 'MST' : MT,
'MDT' : MT, 'PST' : PT, 'PDT' : PT}
dt_est
# datetime.datetime(2014, 1, 2, 4, 0,
tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern')) dt_pst
# datetime.datetime(2016, 3, 11, 16, 0,
tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))
It is worth noting that if using a pytz time zone with this method, it will not
be properly localized:
from dateutil.parser import parse import pytz
EST = pytz.timezone('America/New_York' )
dt = parse('2014-02-03 09:17:00 EST' , tzinfos= {'EST' : EST})
This simply attaches the pytz time zone to the datetime:
dt.tzinfo # Will be in Local Mean Time!
# <DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
If using this method, you should probably relocalize the naive portion of the
datetime after parsing:
2016-07-21
2016-07-22
2016-07-23
2016-07-24
2016-07-25
2016-07-26
2016-07-27
(a-b).days
#4
(a-b).total_seconds()
# 518399.0
Section 6.2: Outputting datetime object to string
Chapter 7: Enum
Section 7.1: Creating an enum (Python 2.4 through 3.3)
Enums have been backported from Python 3.4 to Python 2.4 through Python
3.3. You can get this the enum34 backport from PyPI.
pip install enum34
Creation of an enum is identical to how it works in Python 3.4+
from enum import Enum
class Color(Enum):
red = 1
green = 2
blue = 3
class Color(Enum):
red = 1
green = 2
blue = 3
Chapter 8: Set
Section 8.1: Operations on sets
# Intersection
{1 , 2 , 3 , 4 , 5 }.intersection({3 , 4 , 5 , 6 }) # {3, 4, 5} {1 , 2 , 3 , 4 , 5 } & {3
4, 5}
# Union
{1 , 2 , 3 , 4 , 5 }.union({3 , 4 , 5 , 6 }) # {1, 2, 3, 4, 5, 6} {1 , 2 , 3 , 4 , 5 } | {3
2, 3, 4, 5, 6}
# Difference
{1 , 2 , 3 , 4 }.difference({2 , 3 , 5 }) # {1, 4}
{1 , 2 , 3 , 4 } - {2 , 3 , 5 } # {1, 4}
# Superset check
{1 , 2 }.issuperset({1 , 2 , 3 }) # False
{1 , 2 } >= {1 , 2 , 3 } # False
# Subset check
{1 , 2 }.issubset({1 , 2 , 3 }) # True
{1 , 2 } <= {1 , 2 , 3 } # True
# Disjoint check
{1 , 2 }.isdisjoint({3 , 4 }) # True
{1 , 2 }.isdisjoint({1 , 4 }) # False
# Existence check
2 in {1 , 2 , 3 } # True
4 in {1 , 2 , 3 } # False
4 not in {1 , 2 , 3 } # True
Note that the set is not in the same order as the original list; that is because
sets are unordered , just like dict s.
This can easily be transformed back into a List with Python's built in list
function, giving another list that is the same list as the original but without
duplicates:
list (unique_restaurants)
# ['Chicken Chicken', "McDonald's", 'Burger King']
It's also common to see this as one line:
# Removes all duplicates and returns another list list (set (restaurants))
Now any operations that could be performed on the original list can be done
again.
>>> a.difference(b) {1 , 2 }
>>> b.difference(a) {5 }
Symmetric Difference
a.symmetric_difference(b) returns a new set with elements present in either a
or b but not in both
>>> a.symmetric_difference(b) {1 , 2 , 5 }
>>> b.symmetric_difference(a) {1 , 2 , 5 }
>>> c = {1 , 2 }
>>> c.issubset(a) True
>>> a.issuperset(c) True
Disjoint sets
Sets a and d are disjoint if no element in a is also in d and vice versa.
>>> d = {5 , 6 }
>>> a.isdisjoint(b) # {2, 3, 4} are in both sets False
>>> a.isdisjoint(d)
True
Testing membership
The builtin in keyword searches for occurances
>>> 1 in a True
>>> 6 in a False
Length
The builtin len () function returns the number of elements in the set
By saving the strings 'a' , 'b' , 'b' , 'c' into a set data structure we've lost the
information on the fact that 'b' occurs twice. Of course saving the elements to
a list would retain this information
but a list data structure introduces an extra unneeded ordering that will slow
down our computations.
For implementing multisets Python provides the Counter class from the
collections module (starting from version 2.7):
Python 2.xVersion ≥ 2.7
>>> from collections import Counter >>> counterA = Counter(['a' , 'b' , 'b' , 'c'
>>> counterA
Counter({'b' : 2 , 'a' : 1 , 'c' : 1 })
a / (b * 1.0 ) # = 1.5
1.0 * a / b # = 1.5
a / b * 1.0 # = 1.0 (careful with order of operations)
int and int (gives an int in Python 2 and a float in Python 3) int and float
(gives a float )
int and complex (gives a complex )
float and float (gives a float )
float and complex (gives a complex )
complex and complex (gives a complex )
Note: the + operator is also used for concatenating strings, lists and tuples:
"first string " + "second string" # = 'first string second string' [1 , 2 , 3 ] + [4 ,
] # = [1, 2, 3, 4, 5, 6]
Section 9.3: Exponentiation
a, b = 2 , 3
(a ** b) # = 8
pow (a, b) # = 8
import math
math .pow (a, b) # = 8.0 (always float; does not allow complex results)
import operator
operator .pow (a, b) # = 8
Another difference between the built-in pow and math .pow is that the built-
in pow can accept three arguments:
a, b, c = 2 , 3 , 2
pow (2 , 3 , 2 ) # 0, calculates (2 ** 3) % 2, but as per Python docs, # does so
more efficiently
Special functions
The function math .sqrt(x) calculates the square root of x.
import math
import cmath
c=4
math .sqrt(c) # = 2.0 (always float; does not allow complex results) cmath
.sqrt(c) # = (2+0j) (always complex)
To compute other roots, such as a cube root, raise the number to the
reciprocal of the degree of the root. This could be done with any of the
exponential functions or operator.
import math
x=8
math .pow (x, 1 /3 ) # evaluates to 2.0 x**(1 /3 ) # evaluates to 2.0
a+=1
# and
a *= 2
Any mathematic operator can be used before the '=' character to make an
inplace operation:
Other in place operators exist for the bitwise operators (^, | etc)
Note: The * operator is also used for repeated concatenation of strings, lists,
and tuples:
3 * 'ab' # = 'ababab'
3 * ('a' , 'b' ) # = ('a', 'b', 'a', 'b', 'a', 'b')
Special variations of the math .log function exist for different bases.
# Logarithm base e - 1 (higher precision for low values) math .log1p(5 ) # =
1.791759469228055
# Logarithm base 2
math .log2(8 ) # = 3.0
# Logarithm base 10
math .log10(100 ) # = 2.0 cmath .log10(100 ) # = (2+0j)
operator .mod(3 , 4 ) # 3
operator .mod(10 , 2 ) # 0
operator .mod(6 , 4 ) # 2
- 9 % 7 # 5 9 % 7 # -5
-9 % 7 # -2
If you need to find the result of integer division and modulus, you can use the
divmod function as a shortcut:
quotient, remainder = divmod (9 , 4 )
# quotient = 2, remainder = 1 as 4 * 2 + 1 == 9
The ~ operator will flip all of the bits in the number. Since computers use
signed number representations — most notably, the two's complement
notation to encode negative binary numbers where negative numbers are
written with a leading one (1) instead of a leading zero (0).
This means that if you were using 8 bits to represent your two's-complement
numbers, you would treat patterns from 0000 0000 to 0111 1111 to represent
numbers from 0 to 127 and reserve 1xxx xxxx to represent negative numbers.
In essence, this means that whereas 1010 0110 has an unsigned value of 166
(arrived at by adding (128 * 1 ) + (64 * 0 ) + (32 * 1 ) + (16 * 0 ) + (8 * 0 ) +
(4 * 1 ) + (2 * 1 ) + (1 * 0 )), it has a two's-complement value of -90 (arrived
at by adding (128 * 1 ) - (64 * 0 ) - (32 * 1 ) - (16 * 0 ) - (8 * 0 ) - (4 * 1 ) - (2
* 1 ) (1 * 0 ), and complementing the value).
In this way, negative numbers range down to -128 (1000 0000 ). Zero (0) is
represented as 0000 0000 , and minus one (-1) as 1111 1111 .
In general, though, this means ~ n = -n - 1 .
# 0 = 0b0000 0000 ~ 0
# Out: -1
# -1 = 0b1111 1111
# 1 = 0b0000 0001 ~ 1
# Out: -2
# -2 = 1111 1110
# 2 = 0b0000 0010 ~ 2
# Out: -3
# -3 = 0b1111 1101
# 123 = 0b0111 1011 ~ 123
# Out: -124
# -124 = 0b1000 0100
Note , the overall effect of this operation when applied to positive numbers
can be summarized:
~ n > -|n+1 |
And then, when applied to negative numbers, the corresponding effect is:
~ -n > |n1 |
The following examples illustrate this last rule...
# -0 = 0b0000 0000
~ -0
# Out: -1
# -1 = 0b1111 1111
# 0 is the obvious exception to this rule, as -0 == 0 always
# -1 = 0b1000 0001 ~ -1
# Out: 0
# 0 = 0b0000 0000
# -2 = 0b1111 1110 ~ -2
# Out: 1
# 1 = 0b0000 0001
#0^0=0
#0^1=1
#1^0=1
#1^1=0
# 60 = 0b111100 # 30 = 0b011110 60 ^ 30
# Out: 34
# 34 = 0b100010
#0&0=0
#0&1=0
#1&0=0
#1&1=1
# 60 = 0b111100
# 30 = 0b011110
60 & 30
# Out: 28
# 28 = 0b11100
#0|0=0
#0|1=1
#1|0=1
#1|1=1
# 60 = 0b111100
# 30 = 0b011110
60 | 30
# Out: 62
# 62 = 0b111110
# 2 = 0b10 2 << 2
# Out: 8
# 8 = 0b1000
The >> operator will perform a bitwise "right shift," where the left operand's
value is moved right by the number of bits given by the right operand.
# 8 = 0b1000
8 >> 2
# Out: 2
# 2 = 0b10
bin(8 >> 2 )
# Out: 0b10
Performing a right bit shift of 1 is equivalent to integer division by 2:
36 >> 1
# Out: 18
15 >> 1 # Out: 7
Performing a right bit shift of n is equivalent to integer division by 2 **n:
48 >> 4 # Out: 3
59 >> 3 # Out: 7
a = 0b001
a &= 0b010
# a = 0b000
a = 0b001
a |= 0b010
# a = 0b011
a = 0b001
a <<= 2
# a = 0b100
a = 0b100
a >>= 2
# a = 0b001
a = 0b101
a ^= 0b011
# a = 0b110
When you use or, it will either return the first value in the expression if it's
true, else it will blindly return the second value. I.e. or is equivalent to:
def or_(a, b):
if a:
return a
else :
return b
For and , it will return its first value if it's false, else it returns the last value:
def and_(a, b): if not a: return a else :
return b
In Python you can compare a single element using two binary operators--one
on either side:
if 3.14 < x < 3.142 :
print ("x is near pi" )
In many (most?) programming languages, this would be evaluated in a way
contrary to regular math: (3.14 < x) < 3.142 , but in Python it is treated like
3.14 < x and x < 3.142 , just like most non-programmers would expect.
Evaluates to the second argument if and only if both of the arguments are
truthy. Otherwise evaluates to the first falsey argument.
x = True
y = True
z = x and y # z = True
x = True
y = False
z = x and y # z = False
x = False
y = True
z = x and y # z = False
x = False
y = False
z = x and y # z = False
x=1
y=1
z = x and y # z = y, so z = 1, see `and` and `or` are not guaranteed to be a
boolean
x=0
y=1
z = x and y # z = x, so z = 0 (see above)
x=1
y=0
z = x and y # z = y, so z = 0 (see above)
x=0
y=0
z = x and y # z = x, so z = 0 (see above)
The 1's in the above example can be changed to any truthy value, and the 0's
can be changed to any falsey value.
Section 11.5: or
Evaluates to the first truthy argument if either one of the arguments is truthy.
If both arguments are falsey, evaluates to the second argument.
x = True
y = True
z = x or y # z = True
x = True
y = False
z = x or y # z = True
x = False
y = True
z = x or y # z = True
x = False
y = False
z = x or y # z = False
x=1
y=1
z = x or y # z = x, so z = 1, see `and` and `or` are not guaranteed to be a
boolean
x=1
y=0
z = x or y # z = x, so z = 1 (see above)
x=0
y=1
z = x or y # z = y, so z = 1 (see above)
x=0
y=0
z = x or y # z = y, so z = 0 (see above)
The 1's in the above example can be changed to any truthy value, and the 0's
can be changed to any falsey value.
>>> a, b, c, d = 2 , 3 , 5 , 7
>>> a ** (b + c) # parentheses
256
>>> a * b ** c # exponent: same as `a * (b ** c)`
7776
>>> a + b * c / d # multiplication / division: same as `a + (b * c / d)`
4.142857142857142
Python 3 added a new keyword called nonlocal . The nonlocal keyword adds
a scope override to the inner scope. You can read all about it in PEP 3104 .
This is best illustrated with a couple of code examples. One of the most
common examples is to create function that can increment:
def counter():
num = 0
def incrementer():
num + = 1
return num
return incrementer
If you try running this code, you will receive an UnboundLocalError
because the num variable is referenced before it is assigned in the innermost
function. Let's add nonlocal to the mix:
def counter():
num = 0
def incrementer():
return incrementer
c = counter() c() # = 1
c() # = 2
c() # = 3
Basically nonlocal will allow you to assign to variables in an outer scope, but
not a global scope. So you can't use nonlocal in our counter function because
then it would try to assign to a global scope. Give it a try and you will
quickly get a SyntaxError . Instead you must use nonlocal in a nested
function.
In Python, variables inside functions are considered local if and only if they
appear in the left side of an assignment statement, or some other binding
occurrence; otherwise such a binding is looked up in enclosing functions, up
to the global scope. This is true even if the assignment statement is never
executed.
x = 'Hi'
def read_x():
print (x) # x is just referenced, therefore assumed global
read_x() # prints Hi
def read_y():
print (y) # here y is just referenced, therefore assumed global read_y() #
NameError: global name 'y' is not defined
def read_y():
y = 'Hey' # y appears in an assignment, therefore it's local print (y) # will find
the local y
def change_local_x():
x = 'Bye'
print (x)
def foo():
a=5
print (a) # ok
x=5
print (x) # out: 5
del x
print (x) # NameError: name 'f' is not defined
Note that del is a binding occurrence , which means that unless explicitly
stated otherwise (using nonlocal or global ), del v will make v local to the
current scope. If you intend to delete v in an outer scope, use nonlocal v or
global v in the same scope of the del v statement.
a = A()
a.x = 7
print (a.x) # out: 7
del a.x
print (a.x) # error: AttributeError: 'A' object has no attribute 'x'
del v[item]
This command triggers a call to v.__delitem__ (item).
The intention is that item will not belong in the mapping implemented by the
object v. For example:
x = {'a' : 1 , 'b' : 2 }
del x['a' ]
print (x) # out: {'b': 2}
print (x['a' ]) # error: KeyError: 'a'
del v[a:b]
This actually calls v.__delslice__ (a, b).
The intention is similar to the one described above, but with slices - ranges of
items instead of a single item. For example:
x = [0 , 1 , 2 , 3 , 4 ]
del x[1 :3 ]
print (x) # out: [0, 3, 4]
Classes have a local scope during definition, but functions inside the class do
not use that scope when looking up names. Because lambdas are functions,
and comprehensions are implemented using function scope, this can lead to
some surprising behavior.
a = 'global'
class Fred:
a = 'class' # class scope
b = (a for i in range (10 )) # function scope c = [a for i in range (10 )] #
function scope d = a # class scope
e = lambda : a # function scope
f = lambda a= a: a # default argument uses class scope
class A:
a = 42
b = list (a + i for i in range (10 ))
This example uses references from this answer by Martijn Pieters, which
contains more in depth analysis of this behavior.
def func():
bar = 2 # local
print (foo) # prints variable foo from global scope
print (bar) # prints variable bar from local scope
One can inspect which variables are in which scope. Built-in functions locals
() and globals () return the whole scopes as dictionaries.
foo = 1
def func():
bar = 2
print (globals ().keys()) # prints all variable names in global scope print
(locals ().keys()) # prints all variable names in local scope
# global variable foo still exists, unchanged: print (globals ()['foo' ]) # prints
1
print (locals ()['foo' ]) # prints 2
def func():
global foo
foo = 2 # this modifies the global foo, rather than creating a local variable
def func():
# This function has a local variable foo, because it is defined down below. #
So, foo is local from this point. Global foo is hidden.
def f2():
baz = 2
# here, foo is a global variable, baz is a local variable # bar is not in either
scope
print (locals ().keys()) # ['baz']
print ('bar' in locals ()) # False
print ('bar' in globals ()) # False
def f3():
baz = 3
print (bar) # bar from f1 is referenced so it enters local scope of f3 (closure)
print (locals ().keys()) # ['bar', 'baz']
print ('bar' in locals ()) # True
print ('bar' in globals ()) # False
def f4():
bar = 4 # a new local bar which hides bar from local scope of f1 baz = 4
print (bar)
print (locals ().keys()) # ['bar', 'baz']
print ('bar' in locals ()) # True
print ('bar' in globals ()) # False
def f3():
foo = 3 # a new foo local in f3 print (foo) # 3
foo = 30 # modifies local foo in f3 only
def f4():
global foo
print (foo) # 0
foo = 100 # modifies global foo
def f3():
nonlocal foo # foo from f2, which is the nearest enclosing scope print (foo) #
2
foo = 20 # modifies foo from f2!
x=5
x += 7
for x in iterable: pass
The order of the arguments is different from many other languages (such as
C, Ruby, Java, etc.), which may lead to bugs when people unfamiliar with
Python's "surprising" behaviour use it (they may reverse the order). Some
find it "unwieldy", since it goes contrary to the normal flow of thought
(thinking of the condition first and then the effects).
n=5
"Greater than 2" if n > 2 else "Smaller than or equal to 2"
# Out: 'Greater than 2'
The result of this expression will be as it is read in English - if the conditional
expression is True, then it will evaluate to the expression on the left side,
otherwise, the right side.
Ternary operations can also be nested, as here:
n=5
"Hello" if n > 10 else "Goodbye" if n > 5 else "Good day"
They also provide a method of including conditionals in lambda functions.
if number > 2 :
print ("Number is bigger than 2." )
elif number < 2 : # Optional clause (you can have multiple elifs)
print ("Number is smaller than 2." )
else : # Optional clause (you can only have one else)
print ("Number is 2." )
Outputs Number is bigger than 2 Using else if instead of elif will trigger a
syntax error and is not allowed.
The following values are considered falsey, in that they evaluate to False
when applied to a boolean operator. None
False
0, or any numerical value equivalent to zero, for example 0L, 0.0 , 0j Empty
sequences: '', "" , (), []
Empty mappings: {}
User-defined types where the __bool__ or __len__ methods return 0 or False
>>> a = 1
>>> b = 6
>>> if a and b > 2 : ... print ('yes' ) ... else :
... print ('no' )
yes
Each variable needs to be compared separately.
>>> if a > 2 and b > 2 : ... print ('yes' ) ... else :
... print ('no' )
no
>>> a = 1
>>> if a == 3 or 4 or 6 : ... print ('yes' ) ... else :
... print ('no' )
yes
Again each comparison must be made separately
no
Using the in operator is the canonical way to write this.
no
This function is removed on Python 3. You can use the cmp_to_key (func )
helper function located in functools in Python 3 to convert old comparison
functions to key functions.
if condition:
body
else :
body
The else statement will execute it's body only if preceding conditional
statements all evaluate to False.
if True :
print "It is true!"
else :
print "This won't get printed.."
# Output: It is true!
if False :
print "This won't get printed.."
else :
print "It is false!"
# Output: It is false!
Section 14.7: Testing if an object is None and assigning it
if condition:
body
The if statements checks the condition. If it evaluates to True , it executes the
body of the if statement. If it evaluates to False , it skips the body.
if True :
print "It is true!"
>> It is true!
if False :
print "This won't get printed.."
The condition can be any valid expression:
if 2 + 2 == 4 :
print "I know math!"
>> I know math !
Chapter 15: Comparisons
Parameter Details
x First item to be compared
y Second item to be compared
You can compare multiple items with multiple comparison operators with
chain comparison. For example
x>y>z
is just a short form of:
x > y and y > z
This will evaluate to True only if both comparisons are True .
The general form is
a OP b OP c OP d ...
Where OP represents one of the multiple comparison operations you can use,
and the letters represent arbitrary valid expressions.
Style
There is no theoretical limit on how many items and comparison operations
you use as long you have proper syntax:
1 > 1 < 2 > 0.5 < 100 != 24
The above returns True if each comparison returns True . However, using
convoluted chaining is not a good style. A good chaining will be
"directional", not more complicated than
1 > x > 4 > y != 8
Side effects
As soon as one comparison returns False , the expression evaluates
immediately to False , skipping all remaining comparisons.
Note that the expression exp in a > exp > b will be evaluated only once,
whereas in the case of
a > exp and exp > b exp will be computed twice if a > exp is true.
a = 'Python is fun!'
b = 'Python is fun!'
a == b # returns True
a is b # returns False
a = [1 , 2 , 3 , 4 , 5 ]
b = a # b references a
a == b # True
a is b # True
b = a[:] # b now references a copy of a
a == b # True
a is b # False [!!]
Beyond this, there are quirks of the run-time environment that further
complicate things. Short strings and small integers will return True when
compared with is, due to the Python machine attempting to use less memory
for identical objects.
a = 'short' b = 'short' c = 5
d=5
a is b # True c is d # True
12 > 4
# True
12 < 4
# False
1<4
# True
x != y
This returns True if x and y are not equal and otherwise returns False .
12 != 1
# True
12 != '12'
# True
'12' != '12'
# False
12 == 12
# True
12 == 1
# False
'12' == '12'
# True
'spam' == 'spam'
# True
'spam' == 'spam '
# False
'12' == 12
# False
Note that each type has to define a function that will be used to evaluate if
two values are the same. For builtin types these functions behave as you'd
expect, and just evaluate things based on being the same value. However
custom types could define equality testing as whatever they'd like, including
always returning True or always returning False .
In order to compare the equality of custom classes, you can override == and
!= by defining __eq__ and __ne__ methods. You can also override __lt__ (<
), __le__ (<= ), __gt__ (> ), and __ge__ (> ). Note that you only need to
override two comparison methods, and Python can handle the rest (== is the
same as not < and not > , etc.)
class Foo(object ):
def __init__ (self , item):
self .my_item = item
def __eq__ (self , other):
return self .my_item == other.my_item
a = Foo(5 )
b = Foo(5 )
a == b # True a != b # False a is b # False
Note that this simple comparison assumes that other (the object being
compared to) is the same object type. Comparing to another type will throw
an error:
class Bar(object ):
def __init__ (self , item):
self .other_item = item
i=0
while i < 7 :
print (i)
if i == 4 :
print ("Breaking from loop" ) break
i += 1
The loop conditional will not be evaluated after the break statement is
executed. Note that break statements are only allowed inside loops ,
syntactically. A break statement inside a function cannot be used to
terminate loops that called that function.
Executing the following prints every digit until number 4 when the break
statement is met and the loop stops:
0
1
2
3
4
Breaking from loop
break statements can also be used inside for loops, the other looping
construct provided by Python:
break
Executing this loop now prints:
0
1
2
Note that 3 and 4 are not printed since the loop has ended. If a loop has an
else clause, it does not execute when the loop is terminated through a break
statement.
continue statement
A continue statement will skip to the next iteration of the loop bypassing the
rest of the current block but continuing the loop. As with break , continue
can only appear inside loops:
for i in (0 , 1 , 2 , 3 , 4 , 5 ): if i == 2 or i == 4 : continue
print (i)
0
1
3
5
Note that 2 and 4 aren't printed, this is because continue goes to the next
iteration instead of continuing on to print (i) when i == 2 or i == 4 .
Nested Loops
break and continue only operate on a single level of loop. The following
example will only break out of the inner for loop, not the outer while loop:
while True :
for i in range (1 , 5 ):
if i == 2 :
break # Will only break out of the inner loop!
Python doesn't have the ability to break out of multiple levels of loop at once
-- if this behavior is desired, refactoring one or more loops into a function and
replacing break with return may be the way to go.
Use return from within a function as a break
The return statement exits from a function, without executing the code that
comes after it.
If you have a loop inside a function, using return from inside that loop is
equivalent to having a break as the rest of the code of the loop is not
executed (note that any code after the loop is not executed either ):
def break_loop():
for i in range (1 , 5 ): if (i == 2 ): return (i) print (i)
return (5 )
If you have nested loops, the return statement will break all loops:
def break_all():
for j in range (1 , 5 ): for i in range (1 , 4 ):
will output:
1 # 1*1
2 # 1*2
3 # 1*3
4 # 1*4
2 # 2*1
4 # 2*2
# return because 2*3 = 6, the remaining iterations of both loops are not
executed
for loops iterate over a collection of items, such as list or dict , and run a
block of code with each element from the collection.
for i in [0 , 1 , 2 , 3 , 4 ]: print (i)
The above for loop iterates over a list of numbers.
Each iteration sets the value of i to the next element of the list. So first it will
be 0, then 1, then 2, etc. The output will be as follow:
0
1
2
3
4
for loop can iterate on any iterable object which is an object which defines a
__getitem__ or a __iter__ function. The __iter__ function returns an iterator,
which is an object with a next function that is used to access the next element
of the iterable.
one
two
three four
The range function generates numbers which are also often used in a for loop.
for x in range (1 , 6 ): print (x)
The result will be a special range sequence type in python >=3 and a list in
python <=2. Both can be looped through using the for loop.
1
2
3
4
5
If you want to loop though both the elements of a list and have an index for
the elements as well, you can use Python's enumerate function:
for index, item in enumerate (['one' , 'two' , 'three' , 'four' ]): print (index, '::' ,
enumerate will generate tuples, which are unpacked into index (an integer)
and item (the actual value from the list). The above loop will print
Iterate over a list with value manipulation using map and lambda , i.e. apply
lambda function on each element in the list:
x = map (lambda e : e.upper(), ['one' , 'two' , 'three' , 'four' ]) print (x)
Output:
['ONE' , 'TWO' , 'THREE' , 'FOUR' ] # Python 2.x
NB: in Python 3.x map returns an iterator instead of a list so you in case you
need a list you have to cast the result print (list (x))
i=0
while i < 3 :
print (i)
i += 1
else :
print ('done' )
output:
0
1
2
done
The else clause does not execute if the loop terminates some other way
(through a break statement or by raising an exception):
break
else :
print ('done' ) output:
01
Most other programming languages lack this optional else clause of loops.
The use of the keyword else in particular is often considered confusing.
The original concept for such a clause dates back to Donald Knuth and the
meaning of the else keyword becomes clear if we rewrite a loop in terms of if
statements and goto statements from earlier days before structured
programming or from a lower-level assembly language.
For example:
while loop_condition(): ...
if break_condition():
break
...
is equivalent to:
# pseudocode
<< start>> :
if loop_condition(): ...
if break_condition(): goto << end>>
...
goto << start>>
<< end>> :
These remain equivalent if we attach an else clause to each of them.
For example:
break
...
else :
print ('done' )
is equivalent to:
# pseudocode
<< start>> :
if loop_condition(): ...
if break_condition(): goto << end>>
...
goto << start>>
else :
print ('done' )
<< end>> :
A for loop with an else clause can be understood the same way.
Conceptually, there is a loop condition that remains True as long as the
iterable object or sequence still has some remaining elements.
Why would one use this strange construct?
The main use case for the for ...else construct is a concise implementation of
search as for instance:
a = [1 , 2 , 3 , 4 ]
for i in a:
if type (i) is not int : print (i)
break
else :
print ("no exception" )
To make the else in this construct less confusing one can think of it as "if not
break " or "if not found ".
Some discussions on this can be found in [Python-ideas] Summary of
for...else threads , Why does python use 'else' after for and while loops? , and
Else Clauses on Loop Statements
"a"
"b"
"c"
1
2
3
a :: 1
b :: 2
c :: 3
Note that in Python 2, .keys(), .values() and .items() return a list object. If
you simply need to iterate through the result, you can use the equivalent
.iterkeys(), .itervalues() and .iteritems().
Note also that in Python 3, Order of items printed in the above manner does
not follow any order.
a = 10
while True :
a = a1
print (a)
if a< 7 :
break print ('Done.' )
9
8
7
6
Done.
Suppose you have a long list of elements and you are only interested in every
other element of the list. Perhaps you only want to examine the first or last
elements, or a specific range of entries in your list. Python has strong
indexing built-in capabilities. Here are some examples of how to achieve
these scenarios.
abcde
Often you need both the element and the index of that element. The
enumerate keyword performs that task.
for idx, s in enumerate (lst):
print ("%s has an index of %d" % (s, idx))
The index idx will start with zero and increment for each iteration, while the s
will contain the element being processed. The previous snippet will output:
alpha has an index of 0 bravo has an index of 1 charlie has an index of 2 delta
has an index of 3 echo has an index of 4
i=0
while i < 4 :
#loop statements
i=i+1
While the above loop can easily be translated into a more elegant for loop,
while loops are useful for checking if some condition has been met. The
following loop will continue to execute until myObject is ready.
myObject = anObject()
while myObject.isNotReady(): myObject.tryToGetReady() while loops can
also run without a condition by using numbers (complex or real) or True :
import cmath
Individual elements can be accessed through indexes. Python arrays are zero-
indexed. Here is an example:
An array is a data structure that stores values of same data type. In Python,
this is the main difference between arrays and lists.
While python lists can contain values corresponding to different data types,
arrays in python can only contain values corresponding to same data type. In
this tutorial, we will understand the Python arrays with few examples.
If you are new to Python, get started with the Python Introduction article.
To use arrays in python language, you need to import the standard array
module. This is because array is not a fundamental data type like strings,
integer etc. Here is how you can import array module in python :
from array import *
Once you have imported the array module, you can declare an array. Here is
how you do it:
arrayIdentifierName = array (typecode, [Initializers])
In the declaration above, arrayIdentifierName is the name of array, typecode
lets python know the type of array and Initializers are the values with which
array is initialized.
Typecodes are the codes that are used to define the type of array values or the
type of array. The table in the parameters section shows the possible values
you can use when declaring an array and it's type.
Here is a real world example of python array declaration :
my_array = array ('i' , [1 , 2 , 3 , 4 ])
In the example above, typecode used is i. This typecode represents signed
integer whose size is 2 bytes.
Here is a simple example of an array containing 5 integers
print (i)
#1
#2
#3
#4
#5
Note that the value 6 was appended to the existing array values.
We can use the insert() method to insert a value at any index of the array.
Here is an example :
In the above example, the value 0 was inserted at index 0. Note that the first
argument is the index while second argument is the value.
A python array can be extended with more than one value using extend()
method. Here is an example :
my_array = array ('i' , [1 , 2 , 3 , 4 , 5 ])
my_extnd_array = array ('i' , [7 , 8 , 9 , 10 ])
my_array.extend(my_extnd_array)
# array('i', [1, 2, 3, 4, 5, 7, 8, 9, 10])
We see that the array my_array was extended with values from
my_extnd_array.
Section 17.6: Add items from list into array using fromlist()
method
Here is an example:
So we see that the values 11,12 and 13 were added from list c to my_array.
Section 17.9: Fetch any element through its index using index()
method
index() returns first index of the matching value. Remember that arrays are
zero-indexed.
Note in that second example that only one index was returned, even though
the value exists twice in the array
here the outer list lst has three things in it. each of those things is another list:
The first one is: [ 1 , 2 , 3 ] , the second one is: [ 4 , 5 , 6 ] and the third one is:
. You can access these lists the same way you would access another other
element of a list, like this:
print (lst[0 ])
#output: [1, 2, 3]
print (lst[1 ])
#output: [4, 5, 6]
print (lst[2 ])
#output: [7, 8, 9]
You can then access the different elements in each of those lists the same
way:
print (lst[0 ][0 ])
#output: 1
print (lst[0 ][1 ])
#output: 2
Here the first number inside the [] brackets means get the list in that position.
In the above example we used the number 0 to mean get the list in the 0th
position which is [ 1 , 2 , 3 ] . The second set of [] brackets means get the item in
that position from the inner list. In this case we used both 0 and 1 the 0th
position in the list we got is the number 1 and in the 1st position it is 2
You can also set values inside these lists the same way:
lst[0 ]= [10 , 11 , 12 ]
Now the list is [[ 10 , 11 , 12 ],[ 4 , 5 , 6 ],[ 7 , 8 , 9 ]] . In this example we changed the
whole first list to be a completely new list.
lst[1 ][2 ]= 15
[[[ 111 , 112 , 113 ], [121 , 122 , 123 ], [131 , 132 , 133 ]], \ [[211 , 212 , 213 ]
222 , 223 ], [231 , 232 , 233 ]], \ [[311 , 312 , 313 ], [321 , 322 , 323 ], [331 , 332
]]]
By nesting the lists like this, you can extend to arbitrarily high dimensions.
Accessing is similar to 2D arrays:
print (myarray)
print (myarray[1 ])
print (myarray[2 ][1 ]) print (myarray[1 ][0 ][2 ]) etc.
creating a dict
Dictionaries can be initiated in many ways:
literal syntax
d = {} # empty dict
d = {'key' : 'value' } # dict with initial values
Python 3.xVersion ≥ 3.5
# Also unpacking one or multiple dictionaries with the literal syntax is
possible
dict comprehension
d = {k:v for k, v in [('key' , 'value' , )]}
see also: Comprehensions
built-in class: dict ()
modifying a dict
To add items to a dictionary, simply create a new key with a value:
d['newkey' ] = 42
It also possible to add list and dictionary as value:
d['new_list' ] = [1 , 2 , 3 ]
d['new_dict' ] = {'nested_dict' : 1 }
To delete an item, delete the key from the dictionary: del d['newkey' ]
Traceback (most recent call last): File "<stdin>" , line 1 , in < module>
KeyError : 'not there'
One way to avoid key errors is to use the dict .get method, which allows you
to specify a default value to return in the case of an absent key.
value = mydict.get(key, default_value)
mydict = {}
print (mydict)
# {}
print (mydict.get("foo" , "bar" )) # bar
print (mydict)
# {}
print (mydict.setdefault("foo" , "bar" )) # bar
print (mydict)
# {'foo': 'bar'}
if key in mydict:
value = mydict[key]
else :
value = default_value
#c3
#b2
#a1
While the values() method can be used to iterate over only the values, as
would be expected:
d = defaultdict(int )
d['key' ] # 0
d['key' ] = 5
d['key' ] # 5
d = defaultdict(lambda : 'empty' )
d['key' ] # 'empty'
d['key' ] = 'full'
d['key' ] # 'full'
[*] Alternatively, if you must use the built-in dict class, using dict
.setdefault() will allow you to create a default whenever you access a key that
did not exist before:
>>> d = {}
{}
>>> d.setdefault('Another_key' , []).append("This worked!" ) >>> d
With this technique the foremost value takes precedence for a given key
rather than the last ("Clifford" is thrown out in favor of "Nemo").
Python 2.x, 3.x
This uses the lattermost value, as with the **-based technique for merging
("Clifford" overrides "Nemo").
>>> fish.update(dog)
>>> fish
{'color' : 'red' , 'hands' : 'paws' , 'name' : 'Clifford' , 'special' : 'gills' }
dict .update uses the latter dict to overwrite the previous one.
print (mydict.keys())
# Python2: ['a', 'b']
# Python3: dict_keys(['b', 'a'])
print (mydict.values())
# Python2: ['1', '2']
# Python3: dict_values(['2', '1'])
If you want to work with both the key and its corresponding value, you can
use the items() method:
print (mydict.items())
# Python2: [('a', '1'), ('b', '2')]
# Python3: dict_items([('b', '2'), ('a', '1')])
NOTE: Because a dict is unsorted, keys(), values(), and items() have no sort
order. Use sort(), sorted (), or an OrderedDict if you care about the order that
these methods return.
Looking up a value like this with a key that does not exist will raise a
KeyError exception, halting execution if uncaught. If we want to access a
value without risking a KeyError , we can use the dictionary.get method. By
default if the key does not exist, the method will return None . We can pass it
a second value to return instead of None in the event of a failed lookup.
w = dictionary.get("whatever" )
x = dictionary.get("whatever" , "nuh-uh" ) In this example w will get the value
None and x will get the value "nuh-uh" .
# Outputs "first 1", "second 2", "third 3", "last 4" for key in d:
print (key, d[key])
This parrot wouldn't VOOM if you put four million volts through it. E' s
bleedin' demised !
As of Python 3.5 you can also use this syntax to merge an arbitrary number
of dict objects.
>>> fish = {'name' : "Nemo" , 'hands' : "fins" , 'special' : "gills" } >>> dog =
{'name' : "Clifford" , 'hands' : "paws" , 'color' : "red" } >>> fishdog = {**fish,
**dog}
>>> fishdog
dict (a= 1 , b= 2 , c= 3 ) # {'a': 1, 'b': 2, 'c': 3} dict ([('d' , 4 ), ('e' , 5 ), ('f' , 6 )])
4, 'e': 5, 'f': 6} dict ([('a' , 1 )], b= 2 , c= 3 ) # {'a': 1, 'b': 2, 'c': 3} dict ({'a' : 1 ,
2 }, c= 3 ) # {'a': 1, 'b': 2, 'c': 3}
car = {}
car["wheels" ] = 4
car["color" ] = "Red"
car["model" ] = "Corvette"
Dictionary values can be accessed by their keys.
print "Little " + car["color" ] + " " + car["model" ] + "!" # This would print
out "Little Red Corvette!"
Dictionaries can also be created in a JSON style:
car = {"wheels" : 4 , "color" : "Red" , "model" : "Corvette" }
Dictionary values can be iterated over:
for key in car:
print key + ": " + car[key]
# wheels: 4
# color: Red
# model: Corvette
options = {
"x" : ["a" , "b" ],
"y" : [10 , 20 , 30 ]
Given a dictionary such as the one shown above, where there is a list
representing a set of values to explore for the corresponding key. Suppose
you want to explore "x" = "a" with "y" = 10 , then "x" = "a" with"y" = 10 , and so
on until you have explored all possible combinations.
You can create a list that returns all such combinations of values using the
following code.
import itertools
options = {
"x" : ["a" , "b" ], "y" : [10 , 20 , 30 ]}
keys = options.keys()
values = (options[key] for key in keys)
combinations = [dict (zip (keys, combination)) for combination in itertools
.product(*values)] print combinations
This gives us the following list stored in the variable combinations:
[{ 'x' : 'a' , 'y' : 10 }, {'x' : 'b' , 'y' : 10 }, {'x' : 'a' , 'y' : 20 }, {'x' : 'b' , 'y' : 20 }, {
'a' , 'y' : 30 }, {'x' : 'b' , 'y' : 30 }]
Note that the append() method only appends one new element to the end of
the list. If you append a list to another list, the list that you append becomes a
single element at the end of the first list.
Lists can also be concatenated with the + operator. Note that this does not
modify any of the original lists:
a = [1 , 2 , 3 , 4 , 5 , 6 ] + [7 , 7 ] + b # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
a.index(7 ) # Returns: 6
a.index(49 ) # ValueError, because 49 is not in a.
a.index(7 , 7 ) # Returns: 7
a.index(7 , 8 ) # ValueError, because there is no 7 starting at index 8
4. insert(index, value) – inserts value just before the specified index. Thus
after the insertion the new element occupies position index.
a.pop( 2 )
# Returns: 5
# a: [0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] a.pop(8 )
# Returns: 7
# a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# With no argument:
a.pop()
# Returns: 10
# a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a.remove( 0 )
a.remove(9 )
# a: [1, 2, 3, 4, 5, 6, 7, 8] a.remove(10 )
# ValueError, because 10 is not in a
a.sort()
# a = [1, 2, 3, 4, 5, 6, 7, 8] # Sorts the list in numerical order
Lists can also be reversed when sorted using the reverse= True flag in the
sort() method.
a.sort(reverse= True )
# a = [8, 7, 6, 5, 4, 3, 2, 1]
If you want to sort by attributes of items, you can use the key keyword
argument:
import datetime
class Person(object ):
def __init__ (self , name, birthday, height): self .name = name
self .birthday = birthday
self .height = height
people = [{'name' :'chandan' , 'age' :20 , 'salary' :2000 }, {'name' :'chetan' , 'age'
:18 , 'salary' :5000 }, {'name' :'guru' , 'age' :30 , 'salary' :3000 }]
by_age = itemgetter('age' )
by_salary = itemgetter('salary' )
people.sort(key= by_age) #in-place sorting by age people.sort(key=
by_salary) #in-place sorting by salary
itemgetter can also be given an index. This is helpful if you want to sort
based on indices of a tuple.
example
13. Copying
The default assignment "=" assigns a reference of the original list to the new
name. That is, the original name and new name are both pointing to the same
list object. Changes made through any of them will be reflected in another.
This is often not what you intended.
b=a
a.append(6 )
# b: [1, 2, 3, 4, 5, 6]
If you want to create a copy of the list you have below options.
You can slice it:
new_list = old_list[:]
You can use the built in list() function:
new_list = list (old_list)
You can use generic copy.copy():
import copy
new_list = copy .copy (old_list) #inserts references to the objects found in the
original.
This is a little slower than list() because it has to find out the datatype of
old_list first.
If the list contains objects and you want to copy them as well, use generic
copy.deepcopy():
import copy
new_list = copy .deepcopy(old_list) #inserts copies of the objects found in the
original.
Obviously the slowest and most memory-needing method, but sometimes
unavoidable.
Python 3.xVersion ≥ 3.0
copy () – Returns a shallow copy of the list
aa = a.copy ()
# aa = [1, 2, 3, 4, 5]
lst = [1 , 2 , 3 , 4 ]
lst[0 ] # 1
lst[1 ] # 2
Attempting to access an index outside the bounds of the list will raise an
IndexError .
lst[4 ] # IndexError: list index out of range
Negative indices are interpreted as counting from the end of the list.
lst[1 ] # 4
lst[2 ] # 3
lst[5 ] # IndexError: list index out of range
Lists allow to use slice notation as lst[start:end:step]. The output of the slice
notation is a new list containing elements from index start to end1 . If options
are omitted start defaults to beginning of list, end to end of list and step to 1:
lst[ 1 :] # [2, 3, 4]
lst[:3 ] # [1, 2, 3]
lst[::2 ] # [1, 3]
lst[::1 ] # [4, 3, 2, 1]
lst[1 :0 :1 ] # [4, 3, 2]
lst[5 :8 ] # [] since starting index is greater than length of lst, returns empty
list lst[1 :10 ] # [2, 3, 4] same as omitting ending index
With this in mind, you can print a reversed version of the list by calling
lst[::1 ] # [4, 3, 2, 1]
When using step lengths of negative amounts, the starting index has to be
greater than the ending index otherwise the result will be an empty list.
lst[3 :1 :1 ] # [4, 3]
Using negative step indices are equivalent to the following code:
reversed (lst)[0 :2 ] # 0 = 1 -1 # 2 = 3 -1
The indices used are 1 less than those used in negative indexing and are
reversed.
Advanced slicing
When lists are sliced the __getitem__ () method of the list object is called,
with a slice object. Python has a builtin slice method to generate slice objects.
We can use this to store a slice and reuse it later like so,
# Output: foo
# Output: bar
# Output: baz
You can also get the position of each item at the same time:
for (index, item) in enumerate (my_list):
print ('The item in position {} is: {}' .format(index, item))
# Output: The item in position 0 is: foo # Output: The item in position 1 is:
bar # Output: The item in position 2 is: baz
Note that changing items in a list while iterating on it may have unexpected
results:
# Output: foo # Output: baz In this last example, we deleted the first item at
the first iteration, but that caused bar to be skipped.
Python makes it very simple to check whether an item is in a list. Simply use
the in operator.
lst = ['test' , 'twest' , 'tweast' , 'treast' ]
'test' in lst
# Out: True
'toast' in lst
# Out: False
Note: the in operator on sets is asymptotically faster than on lists. If you need
to use it many times on potentially large lists, you may want to convert your
list to a set , and test the presence of elements on the set .
nums = [1 , 1 , 0 , 1 ]
all (nums)
# False
chars = ['a' , 'b' , 'c' , 'd' ]
all (chars)
# True
nums = [1 , 1 , 0 , 1 ]
any (nums)
# True
vals = [None , None , None , False ] any (vals)
# False
While this example uses a list, it is important to note these built-ins work
with any iterable, including generators.
vals = [1 , 2 , 3 , 4 ]
any (val > 12 for val in vals) # False
any ((val * 2 ) > 6 for val in vals) # True
# Output: # a1 b1
# a2 b2
# a3 b3
If the lists have different lengths then the result will include only as many
elements as the shortest one:
alist = ['a1' , 'a2' , 'a3' ] blist = ['b1' , 'b2' , 'b3' , 'b4' ] for a, b in zip (alist, blist):
print (a, b)
# Output: # a1 b1
# a2 b2
# a3 b3
alist = []
len (list (zip (alist, blist)))
# Output: # 0
For padding lists of unequal length to the longest one with None s use
itertools .zip_longest (itertools .izip_longest in Python 2)
# Output:
# a1 b1 c1
# a2 None c2 # a3 None c3 # None None c4
Removing duplicate values in a list can be done by converting the list to a set
(that is an unordered collection of distinct objects). If a list data structure is
needed, then the set can be converted back to a list using the function list ():
import collections
>>> collections .OrderedDict.fromkeys(names).keys() # Out: ['aixk', 'duke',
'edik', 'tofp']
If one of the lists is contained at the start of the other, the shortest list wins.
[1 , 10 ] < [1 , 10 , 100 ] # True
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#[12, 13, 14]
else
else can be used in List comprehension constructs, but be careful regarding
the syntax. The if/else clauses should be used before for loop, not after:
# create a list of characters in apple, replacing non vowels with '*' # Ex -
'apple' --> ['a', '*', '*', '*' ,'e']
[x for x in 'apple' if x in 'aeiou' else '*' ] #SyntaxError: invalid syntax
# When using if/else together use them before the loop [x if x in 'aeiou' else '*'
for x in 'apple' ] #['a', '*', '*', '*', 'e']
Double Iteration
Order of double iteration [... for x in ... for y in ...] is either natural or
counter-intuitive. The rule of thumb is to follow an equivalent for loop:
def foo(i):
return i, i + 0.5
for i in range (3 ): for x in foo(i): yield str (x) This becomes:
[str (x)
for i in range (3 ) for x in foo(i) ]
This can be compressed into one line as [str (x) for i in range (3 ) for x in
foo(i)]
In-place Mutation and Other Side Effects
Before using list comprehension, understand the difference between functions
called for their side effects (mutating , or in-place functions) which usually
return None , and functions that return an interesting value.
Many functions (especially pure functions) simply take an object and return
some object. An in-place function modifies the existing object, which is
called a side effect . Other examples include input and output operations such
as printing.
list . sort() sorts a list in-place (meaning that it modifies the original list) and
returns the value None . Therefore, it won't work as expected in a list
comprehension:
[x.sort() for x in [[2 , 1 ], [4 , 3 ], [0 , 1 ]]] # [None, None, None]
Instead, sorted () returns a sorted list rather than sorting in-place:
[sorted (x) for x in [[2 , 1 ], [4 , 3 ], [0 , 1 ]]] # [[1, 2], [3, 4], [0, 1]]
Using comprehensions for side-effects is possible, such as I/O or in-place
functions. Yet a for loop is usually more readable. While this works in
Python 3:
[print (x) for x in (1 , 2 , 3 )]
Instead use:
for x in (1 , 2 , 3 ): print (x)
In some situations, side effect functions are suitable for list comprehension.
random . randrange() has the side effect of changing the state of the random
number generator, but it also returns an interesting value. Additionally, next()
can be called on an iterator.
The following random value generator is not pure, yet makes sense as the
random generator is reset every time the expression is evaluated:
[ x for x
in 'foo'
if x not in 'bar'
Note that this is quite different from the ... if ... else ... conditional expression
(sometimes known as a ternary expression) that you can use for the
<expression> part of the list comprehension. Consider the following
example:
temp = x
else :
temp = 1
numbers.append(2 * temp + 1 )
print (numbers)
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
One can combine ternary expressions and if conditions. The ternary operator
works on the filtered result:
[x if x > 2 else '*' for x in range (10 ) if x % 2 == 0 ] # Out: ['*', '*', 4, 6, 8]
The same couldn't have been achieved just by ternary operator only:
[x if (x > 2 and x % 2 == 0 ) else '*' for x in range (10 )] # Out:['*', '*', '*', '*', 4,
'*', 6, '*', 8, '*'] See also: Filters, which often provide a sufficient alternative
to conditional list comprehensions.
This results in two calls to f(x) for 1,000 values of x: one call for generating
the value and the other for checking the if condition. If f(x) is a particularly
expensive operation, this can have significant performance implications.
Worse, if calling f() has side effects, it can have surprising results.
Instead, you should evaluate the expensive operation only once for each
value of x by generating an intermediate iterable (generator expression) as
follows:
>>> [v for v in (f(x) for x in range (1000 )) if v > 10 ] [16 , 25 , 36 , ...]
Or, using the builtin map equivalent:
>>> [v for v in map (f, range (1000 )) if v > 10 ] [16 , 25 , 36 , ...]
Another way that could result in a more readable code is to put the partial
result ( v in the previous example) in an iterable (such as a list or a tuple) and
then iterate over it. Since v will be the only element in the iterable, the result
is that we now have a reference to the output of our slow function computed
only once:
The shortcuts based on + (including the implied use in sum) are, of necessity,
O(L^2) when there are L sublists -- as the intermediate result list keeps
getting longer, at each step a new intermediate result list object gets allocated,
and all the items in the previous intermediate result must be copied over (as
well as a few new ones added at the end). So (for simplicity and without
actual loss of generality) say you have L sublists of I items each: the first I
items are copied back and forth L-1 times, the second I items L-2 times, and
so on; total number of copies is I times the sum of x for x from 1 to L
excluded, i.e., I * (L**2)/2.
The list comprehension just generates one list, once, and copies each item
over (from its original place of residence to the result list) also exactly once.
print (swapped)
# Out: {a: 1, b: 2, c: 3} Python 2.xVersion ≥ 2.3
If your dictionary is large, consider importing itertools and utilize izip or
imap.
Merging Dictionaries
Combine dictionaries and optionally override old values with a nested
dictionary comprehension.
dict1 = {'w' : 1 , 'x' : 1 }
dict2 = {'x' : 2 , 'y' : 2 , 'z' : 2 }
{k: v for d in [dict1, dict2] for k, v in d.items()} # Out: {'w': 1, 'x': 2, 'y': 2,
'z': 2}
However, dictionary unpacking (PEP 448 ) may be a preferred.
List Comprehensions can use nested for loops. You can code any number of
nested for loops within a list comprehension, and each for loop may have an
optional associated if test. When doing so, the order of the for constructs is
the same order as when writing a series of nested for statements. The general
structure of list comprehensions looks like this:
[ expression for target1 in iterable1 [if condition1] for target2 in iterable2 [if
condition2]... for targetN in iterableN [if conditionN] ]
For example, the following code flattening a list of lists using multiple for
statements:
data = [[1 , 2 ], [3 , 4 ], [5 , 6 ]]
output = [element for each_list in data for element in each_list] print
(output)
# Out: [1, 2, 3, 4, 5, 6]
Live Demo
In both the expanded form and the list comprehension, the outer loop (first
for statement) comes first.
In addition to being more compact, the nested comprehension is also
significantly faster.
In [ 1 ]: data = [[1 , 2 ], [3 , 4 ], [5 , 6 ]]
In [2 ]: def f():
...: output= []
...: for each_list in data:
...: for element in each_list:
...: output.append(element)
...: return output
In [3 ]: timeit f()
1000000 loops, best of 3 : 1.37 µs per loop
In [4 ]: timeit [inner for outer in data for inner in outer]
1000000 loops, best of 3 : 632 ns per loop
data = [[1 ], [2 , 3 ], [4 , 5 ]]
output = [element for each_list in data if len (each_list) == 2
for element in each_list
if element != 5 ]
print (output)
# Out: [2, 3, 4]
Live Demo
For the sake of readability, however, you should consider using traditional
for-loops . This is especially true when nesting is more than 2 levels deep,
and/or the logic of the comprehension is too complex. multiple nested loop
list comprehension could be error prone or it gives unexpected result.
Section 21.6: Generator Expressions
# list comprehension
[x**2 for x in range (10 )]
# Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# generator comprehension
(x**2 for x in xrange (10 ))
# Output: <generator object <genexpr> at 0x11b4b7c80>
Note : We use xrange since it too creates a generator object. If we would use
range, a list would be created. Also, xrange exists only in later version of
python 2. In python 3, range just returns a generator. For more information,
see the Differences between range and xrange functions example.
g.next() # 0
g.next() # 1
g.next() # 4
...
g.next() # 81
Traceback (most recent call last): File "<stdin>" , line 1 , in < module>
StopIteration
"""
Out:
0
1
4
...
81
"""
"""
Out: 0
1
4
.
.
.
81
"""
Use cases
Generator expressions are lazily evaluated, which means that they generate
and return each value only when the generator is iterated. This is often useful
when iterating through large datasets, avoiding the need to create a duplicate
of the dataset in memory:
Another common use case is to avoid iterating over an entire iterable if doing
so is not necessary. In this example, an item is retrieved from a remote API
with each iteration of get_objects(). Thousands of objects may exist, must be
retrieved one-by-one, and we only need to know if an object matching a
pattern exists. By using a generator expression, when we encounter an object
matching the pattern.
def get_objects():
"""Gets objects from an API one by one""" while True :
yield get_next_item()
def object_matches_pattern(obj):
# perform potentially complex calculation return matches_pattern
def right_item_exists():
items = (object_matched_pattern(each) for each in get_objects()) for item in
items:
if item.is_the_right_one:
return True return False
Live Demo
Keep in mind that sets are unordered. This means that the order of the results
in the set may differ from the one presented in the above examples.
Note : Set comprehension is available since python 2.7+, unlike list
comprehensions, which were added in 2.0. In Python 2.2 to Python 2.6, the
set () function can be used with a generator expression to produce the same
result:
Python 2.xVersion ≥ 2.2 set (x for x in range (5 )) # Out: {0, 1, 2, 3, 4}
filter (P, S) is almost always written clearer as [x for x in S if P(x)], and this
has the huge advantage that the most common usages involve predicates that
are comparisons, e.g. x== 42 , and defining a lambda for that just requires
much more effort for the reader (plus the lambda is slower than the list
comprehension). Even more so for map (F, S) which becomes [F(x) for x in
S]. Of course, in many cases you'd be able to use generator expressions
instead.
The following lines of code are considered "not pythonic " and will raise
errors in many python linters.
# Filter:
# P(x) = x % 2 == 0
# S = range(10)
[x for x in range (10 ) if x % 2 == 0 ]
# Map
# F(x) = 2*x
# S = range(10)
[2 *x for x in range (10 )]
# List comprehension
results = [2 *x for x in range (10 ) if x % 2 == 0 ]
Refactoring - Quick Reference
Map
map (F, S) == [F(x) for x in S]
Filter
filter (P, S) == [x for x in S if P(x)] where F and P are functions which
respectively transform input values and return a bool
Note however, if the expression that begins the comprehension is a tuple then
it must be parenthesized:
[x, y for x, y in [(1 , 2 ), (3 , 4 ), (5 , 6 )]]
# SyntaxError: invalid syntax
[(x, y) for x, y in [(1 , 2 ), (3 , 4 ), (5 , 6 )]] # Out: [(1, 2), (3, 4), (5, 6)]
# Count the numbers in `range(1000)` that are even and contain the digit `9`:
print (sum (
1 for x in range (1000 )
if x % 2 == 0 and
'9' in str (x)
))
# Out: 95
l = []
for y in [3 , 4 , 5 ]:
temp = []
for x in [1 , 2 , 3 ]: temp.append(x + y)
l.append(temp)
matrix = [[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]]
[[row[i] for row in matrix] for i in range (len (matrix))] # [[1, 4, 7], [2, 5, 8],
[3, 6, 9]]
Like nested for loops, there is no limit to how deep comprehensions can be
nested.
[[[i + j + k for k in 'cd' ] for j in 'ab' ] for i in '12' ]
# Out: [[['1ac', '1ad'], ['1bc', '1bd']], [['2ac', '2ad'], ['2bc', '2bd']]]
>>> list_1 = [1 , 2 , 3 , 4 ]
>>> list_2 = ['a' , 'b' , 'c' , 'd' ]
>>> list_3 = ['6' , '7' , '8' , '9' ]
# Two lists
>>> [(i, j) for i, j in zip (list_1, list_2)]
[(1 , 'a' ), (2 , 'b' ), (3 , 'c' ), (4 , 'd' )]
# Three lists
>>> [(i, j, k) for i, j, k in zip (list_1, list_2, list_3)]
[(1 , 'a' , '6' ), (2 , 'b' , '7' ), (3 , 'c' , '8' ), (4 , 'd' , '9' )]
# so on ...
a = [1 , 2 , 3 , 4 , 5 ]
# steps through the list backwards (step=-1)
b = a[::1 ]
# built-in list method to reverse 'a'
a.reverse()
if a = b:
print (True )
print (b)
# Output:
# True
# [5, 4, 3, 2, 1]
Returns:
shifted_array - the shifted list
"""
# calculate actual shift amount (e.g., 11 --> 1 if length of the array is 5) s %=
len (array )
# negative numbers
shift_list(my_array, 7 ) >>> [3 , 4 , 5 , 1 , 2 ]
Details
Any python iterable
Function(criteria) on which to group the iterable
Results in
{ 'animal' : [('animal' , 'bear' ), ('animal' , 'duck' )], 'plant' : [('plant' , 'cactus' )],
'vehicle' : [('vehicle' , 'harley' ),
Results
{ 'animal' : [['animal' , 'bear' ], ['animal' , 'duck' ]], 'plant' : [['plant' , 'cactus' ]],
'vehicle' : [['vehicle' , 'harley' ],
dic
Results in
{ 1 : [1 , 1 ],
2 : [2 ],
3 : [3 ],
('persons' , 'man' , 'woman' ): [('persons' , 'man' , 'woman' )], 'cow' : ['cow' ],
'dog' : ['dog' ],
10 : [10 ],
11 : [11 ],
'goat' : ['goat' ]}
Notice here that the tuple as a whole counts as one key in this list
Notice in this example that mulato and camel don't show up in our result.
Only the last element with the specified key shows up. The last result for c
actually wipes out two previous results. But watch the new version where I
have the data sorted first on same key.
Results in
{ 'c' : ['camel' ],
'd' : ['dog' , 'donkey' ],
'g' : ['goat' ],
'm' : ['mongoose' , 'malloo' ],
'persons' : [('persons' , 'man' , 'woman' )], 'w' : ['wombat' ]}
Sorted Version
Results in
['cow' , 'cat' , 'camel' , 'dog' , 'donkey' , 'goat' , 'mulato' , 'mongoose' , 'malloo' ,
'man' , 'woman' ), 'wombat' ]
class Node:
def __init__ (self , val):
self .data = val
self .next = None
def getData(self ):
return self .data
def getNext(self ):
return self .next
def setData(self , val):
self .data = val
def setNext(self , val):
self .next = val
class LinkedList:
def __init__ (self ):
self .head = None
def isEmpty(self ):
"""Check if the list is empty"""
return self .head is None
def size(self ):
"""Return the length/size of the list"""
count = 0
current = self .head
while current is not None :
count += 1
current = current.getNext()
return count
if current.getData() is item:
found = True
else :
current = current.getNext()
return found
if current.getData() is item:
found = True
else :
previous = current
current = current.getNext()
if found:
if previous is None :
self .head = current.getNext()
else :
previous.setNext(current.getNext())
else :
raise ValueError
print 'Value not found.'
raise IndexError
print "Index out of bounds."
current = self .head
previous = None
pos = 0
if position is 0 :
self .add(item)
else :
new_node = Node(item)
while pos < position:
pos += 1
previous = current
current = current.getNext()
previous.setNext(new_node)
new_node.setNext(current)
return pos
def pop(self , position = None ):
"""
If no argument is provided, return and remove the item at the head. If
position is provided, return and remove the item at that position. If index is
out of bounds, raise IndexError
"""
if position > self .size():
previous = current
current = current.getNext()
pos += 1
new_node = Node(item)
if previous is None :
new_node.setNext(current)
self .head = new_node
else :
previous.setNext(new_node)
def printList(self ):
"""Print the list"""
current = self .head
while current is not None :
ll = LinkedList() ll.add('l' )
ll.add('H' )
ll.insert(1 , 'e' ) ll.append('l' ) ll.append('o' ) ll.printList() H e l l o
class Node:
def __init__ (self , cargo= None , next= None ):
self .car = cargo
self .cdr = next
def display(lst):
if lst:
w("%s " % lst) display(lst.cdr)
else :
w("nil \n " )
Details
callable that determines the condition or None then use the identity function
for filtering (positionalonly )
iterable that will be filtered (positional-only )
[name for name in names if len (name) > 5 ] # equivalent list comprehension #
Out: ['Barney']
The next-function gives the next (in this case first) element of and is therefore
the reason why it's short-circuit.
To find the largest items in a collection, heapq module has a function called
nlargest, we pass it two arguments, the first one is the number of items that
we want to retrieve, the second one is the collection name:
import heapq
numbers = [1 , 4 , 2 , 100 , 20 , 50 , 32 , 200 , 150 , 8 ] print (heapq .nlargest(4
numbers)) # [200, 150, 100, 50]
Similarly, to find the smallest items in a collection, we use nsmallest
function:
print (heapq .nsmallest(4 , numbers)) # [1, 2, 4, 8]
people = [
{'firstname' : 'John' , 'lastname' : 'Doe' , 'age' : 30 }, {'firstname' : 'Jane' ,
'lastname' : 'Doe' , 'age' : 25 }, {'firstname' : 'Janie' , 'lastname' : 'Doe' , 'age' : 10
}, {'firstname' : 'Jane' , 'lastname' : 'Roe' , 'age' : 22 }, {'firstname' : 'Johnny' ,
'lastname' : 'Doe' , 'age' : 12 }, {'firstname' : 'John' , 'lastname' : 'Roe' , 'age' : 45
heapq .heapify(numbers)
print (numbers)
# Output: [2, 4, 10, 100, 8, 50, 32, 200, 150, 20]
heapq .heappop(numbers) # 2
print (numbers)
# Output: [4, 8, 10, 100, 20, 50, 32, 200, 150]
heapq .heappop(numbers) # 4
print (numbers)
# Output: [8, 20, 10, 100, 150, 50, 32, 200]
t2 = ('a' , ) # PEP8-compliant
t2 = 'a' , # this notation is not recommended by PEP8
t2 = ('a' , ) # this notation is not recommended by PEP8
t = tuple ('lupins' )
print (t) # ('l', 'u', 'p', 'i', 'n', 's')
t = tuple (range (3 ))
print (t) # (0, 1, 2)
These examples are based on material from the book Think Python by Allen
B. Downey .
>>> t = (1 , 4 , 9 )
>>> t[0 ] = 2
Traceback (most recent call last):
>>> t = (1 , 2 ) >>> q = t
>>> t += (3 , 4 ) >>> t
(1 , 2 , 3 , 4 )
>>> q
(1 , 2 )
Be careful when placing mutable objects, such as lists, inside tuples. This
may lead to very confusing outcomes when changing them. For example:
>>> t = (1 , 2 , 3 , [1 , 2 , 3 ]) (1 , 2 , 3 , [1 , 2 , 3 ])
>>> t[3 ] += [4 , 5 ]
Will both raise an error and change the contents of the list within the tuple:
You can use the += operator to "append" to a tuple - this works by creating a
new tuple with the new element you "appended" and assign it to its current
variable; the old tuple is not changed, but replaced!
This avoids converting to and from a list, but this is slow and is a bad
practice, especially if you're going to append multiple times.
The symbol _ can be used as a disposable variable name if one only needs
some elements of a tuple, acting as a placeholder:
a = 1 , 2 , 3 , 4 _, x, y, _ = a # x == 2
# y == 3
# first == 1
# more == [2, 3, 4]
# last == 5
If we reached the end of one of the lists, the longer list is "larger." If both list
are same it returns 0.
tuple1 = ('a' , 'b' , 'c' , 'd' , 'e' )
tuple2 = ('1' , '2' , '3' )
tuple3 = ('a' , 'b' , 'c' , 'd' , 'e' ) cmp (tuple1, tuple2) Out: 1
cmp (tuple2, tuple1) Out: 1
cmp (tuple1, tuple3) Out: 0
Tuple Length
The function len returns the total length of the tuple
len (tuple1) Out: 5
Max of a tuple
The function max returns item from the tuple with the max value
max (tuple1) Out: 'e'
max (tuple2) Out: '3'
Min of a tuple
The function min returns the item from the tuple with the min value
min (tuple1) Out: 'a'
min (tuple2)
Out: '1'
Convert a list into tuple
The built-in function tuple converts a list into a tuple.
Tuple concatenation
Use + to concatenate two tuples
tuple1 + tuple2
Out: ('a' , 'b' , 'c' , 'd' , 'e' , '1' , '2' , '3' )
Section 28.5: Tuple Are Element-wise Hashable and Equatable
hash ( (1 , 2 ) ) # ok
hash ( ([], {"hello" }) # not ok, since lists and sets are not hashabe
Thus a tuple can be put inside a set or as a key in a dict only if each of its
elements can.
{ (1 , 2 ) } # ok { ([], {"hello" }) ) # not ok
x = (1 , 2 , 3 )
x[0 ] # 1
x[1 ] # 2
x[2 ] # 3
x[3 ] # IndexError: tuple index out of range
Indexing with negative numbers will start from the last element as -1:
x[1 ] # 3
x[2 ] # 2
x[3 ] # 1
x[4 ] # IndexError: tuple index out of range
print (x[:1 ]) # (1, 2) print (x[1 :]) # (3,) print (x[1 :3 ]) # (2, 3)
rev = tuple (reversed (colors)) # rev: ("blue", "green", "red") colors = rev
# colors: ("blue", "green", "red")
Input can also be read from files. Files can be opened using the built-in
function open . Using a with < command> as < name> syntax (called a
'Context Manager') makes using open and getting a handle for the file super
easy:
with open ('somefile.txt' , 'r' ) as fileobj: # write code here using fileobj
This ensures that when code execution leaves the block the file is
automatically closed.
Files can be opened in different modes. In the above example the file is
opened as read-only. To open an existing file for reading only use r. If you
want to read that file as bytes use rb. To append data to an existing file use a.
Use w to create a file or overwrite any existing files of the same name. You
can use r+ to open a file for both reading and writing. The first argument of
open () is the filename, the second is the mode. If mode is left blank, it will
default to r.
with open ('shoppinglist.txt' , 'r' ) as fileobj: # this method makes a list where
each line # of the file is an element in the list lines = fileobj.readlines()
print (lines)
# ['tomato\n', 'pasta\n', 'garlic']
with open ('shoppinglist.txt' , 'r' ) as fileobj:
# here we read the whole content into one string: content = fileobj.read()
# get a list of lines, just like int the previous example: lines = content.split(' \n
)
print (lines)
# ['tomato', 'pasta', 'garlic']
If the size of the file is tiny, it is safe to read the whole file contents into
memory. If the file is very large it is often better to read line-by-line or by
chunks, and process the input in the same loop. To do that:
with open ('shoppinglist.txt' , 'r' ) as fileobj: # this method reads line by line:
lines = []
for line in fileobj:
lines.append(line.strip())
When reading files, be aware of the operating system-specific line-break
characters. Although for line in fileobj automatically strips them off, it is
always safe to call strip() on the lines read, as it is shown above.
Upon reading all the content, the file handler's position will be pointed at the
end of the file:
content = fileobj.read()
end = fileobj.tell()
print ('This file was %u characters long.' % end) # This file was 22
characters long.
fileobj.close()
You can also read any length from the file content during a given call. To do
this pass an argument for read(). When read() is called with no argument it
will read until the end of the file. If you pass an argument it will read that
number of bytes or characters, depending on the mode (rb and r respectively):
fileobj.close()
To demonstrate the difference between characters and bytes:
with open ('shoppinglist.txt' , 'r' ) as fileobj: print (type (fileobj.read())) #
<class 'str'>
with open ('shoppinglist.txt' , 'rb' ) as fileobj: print (type (fileobj.read())) #
<class 'bytes'>
print "Hello," ,
print "World!"
# Hello, World!
If you want more control over the output, you can use sys .stdout.write:
import sys
r r+ w w+ a a+
Python 3 added a new mode for exclusive creation so that you will not
accidentally truncate or overwrite and existing file.
'x' - open for exclusive creation, will raise FileExistsError if the file already
exists
'xb' - open for exclusive creation writing mode in binary. The same as x
except the data is in binary. 'x+' - reading and writing mode. Similar to w+ as
it will create a new file if the file does not exist. Otherwise, will raise
FileExistsError.
'xb+' - writing and reading mode. The exact same as x+ but the data is binary
Allow one to write your file open code in a more pythonic manner:
Python 3.xVersion ≥ 3.3 try :
with open ("fname" , "r" ) as fout: # Work with your open file except
FileExistsError:
# Your error handling goes here
In Python 2 you would have done something like
if os .path.isfile(fname):
with open ("fname" , "w" ) as fout: # Work with your open file else :
# Your error handling goes here
Using the for loop iterator and readline() together is considered bad practice.
More commonly, the readlines() method is used to store an iterable collection
of the file's lines:
The preferred method of file i/o is to use the with keyword. This will ensure
the file handle is closed once the reading or writing has been completed.
with open ('myfile.txt' ) as in_file:
content = in_file.read()
print (content)
or, to handle closing the file manually, you can forgo with and simply call
close yourself:
If you open myfile.txt, you will see that its contents are:
Line 1Line 2Line 3Line 4
Python doesn't automatically add line breaks, you need to do that manually:
Line 1
Line 2
Line 3
Line 4
Do not use os .linesep as a line terminator when writing files opened in text
mode (the default); use \n instead.
If you want to specify an encoding, you simply add the encoding parameter
to the open function:
with open ('my_file.txt' , 'w' , encoding= 'utf-8' ) as f: f.write('utf-8 text' )
It is also possible to use the print statement to write to a file. The mechanics
are different in Python 2 vs Python 3, but the concept is the same in that you
can take the output that would have gone to the screen and send it to a file
instead.
myfile = None
print (s, file = myfile) # writes to stdout print (s, file = None ) # writes to stdout
Unlike using the write function, the print function does automatically add line
breaks.
try :
with open (path) as f:
# File exists
except IOError as e:
# Raise the exception if it is not ENOENT (No such file or directory) if e.errno
!= errno .ENOENT:
raise
# No such file or directory
This will also avoid race-conditions if another process deleted the file
between the check and when it is used. This race condition could happen in
the following cases:
Using the os module:
import os
os .path.isfile('/path/to/some/file.txt' )
Python 3.xVersion ≥ 3.4
Using pathlib:
import pathlib
path = pathlib.Path('/path/to/some/file.txt' ) if path.is_file():
...
To check whether a given path exists or not, you can follow the above EAFP
procedure, or explicitly check the path:
import os
path = "/home/myFiles/directory1"
if os .path.exists(path): ## Do stuff
import shutil
source= '//192.168.1.2/Daily Reports'
destination= 'D: \\ Reports \\ Today'
shutil .copytree(source, destination)
path = '/home/john/temp'
os .path.exists(path)
#this returns false if path doesn't exist or if the path is a broken symbolic link
>>> os .getcwd()
'/Users/csaftoiu/tmp'
>>> os .path.abspath('foo' )
'/Users/csaftoiu/tmp/foo'
>>> os .path.abspath('../foo' )
'/Users/csaftoiu/foo'
>>> os .path.abspath('/foo' )
'/foo'
An iterable is an object that can return an iterator . Any object with state
that has an __iter__ method and returns an iterator is an iterable. It may also
be an object without state that implements a __getitem__ method. - The
method can take indices (starting from zero) and raise an IndexError when
the indices are no longer valid.
An Iterator is an object that produces the next value in a sequence when you
call next(*object *) on some object. Moreover, any object with a __next__
method is an iterator. An iterator raises StopIteration after exhausting the
iterator and cannot be re-used at this point.
Iterable classes:
Iterable classes define an __iter__ and a __next__ method. Example of an
iterable class:
class MyIterable:
def __iter__ (self ):
return self
def __next__(self ):
#code
#Classic iterable object in older versions of python, __getitem__ is still
supported... class MySequence:
def __getitem__ (self , index):
if (condition):
raise IndexError
return (item)
import collections
>>> collections .Iterator()
>>> TypeError : Cant instantiate abstract class Iterator with abstract methods
next
# What was the first item of iterable? No way to get it now. # Only to get a
new iterator
gen()
Python has many built-in functions like print (), input (), len (). Besides
built-ins you can also create your own functions to do more specific jobs—
these are called user-defined functions .
Using the def statement is the most common way to define a function in
python. This statement is a so called single clause compound statement with
the following syntax:
def function_name(parameters): statement(s)
function_name is known as the identifier of the function. Since a function
definition is an executable statement its execution binds the function name to
the function object which can be called later on using the identifier.
parameters is an optional list of identifiers that get bound to the values
supplied as arguments when the function is called. A function may have an
arbitrary number of arguments which are separated by commas.
statement(s) – also known as the function body – are a nonempty sequence of
statements executed each time the function is called. This means a function
body cannot be empty, just like any indented block .
Here’s an example of a simple function definition which purpose is to print
Hello each time it’s called:
def greet():
print ("Hello" )
Now let’s call the defined greet() function:
greet()
# Out: Hello
That’s another example of a function definition which takes one single
argument and displays the passed in value each time the function is called:
def greet_two(greeting): print (greeting)
After that the greet_two() function must be called with an argument:
greet_two("Howdy" ) # Out: Howdy
Also you can give a default value to that function argument:
def greet_two(greeting= "Howdy" ): print (greeting)
Now you can call the function without giving a value:
greet_two() # Out: Howdy
You'll notice that unlike many other languages, you do not need to explicitly
declare a return type of the function. Python functions can return values of
any type via the return keyword. One function can return any number of
different types!
def many_types(x):
if x < 0 :
return "Hello!" else :
return 0
print (many_types(1 )) print (many_types(1 ))
# Output: 0
Hello!
print (i)
list_of_arg_values = [1 , 2 , 3 ]
func(*list_of_arg_values) # Calling it with list of values, * expands the list #
Out: 1
#2
#3
def func(**kwargs):
# kwargs will be a dictionary containing the names as keys and the values as
values for name, value in kwargs.items():
func()
# No Out put # Calling it without arguments
You can't provide these without names, for example func(1 , 2 , 3 ) will raise a
TypeError .
kwargs is a plain native python dictionary. For example, args['value1' ] will
give the value for argument value1. Be sure to check beforehand that there is
such an argument or a KeyError will be raised.
Warning
You can mix these with other optional and required arguments but the order
inside the definition matters.
Note on Uniqueness
Any function can be defined with none or one *args and none or one
**kwargs but not with more than one of each. Also *argsmust be the last
positional argument and **kwargs must be the last parameter. Attempting to
use more than one of either will result in a Syntax Error exception.
It is possible to nest such functions and the usual convention is to remove the
items that the code has already handled but if you are passing down the
parameters you need to pass optional positional args with a * prefix and
optional keyword args with a ** prefix, otherwise args with be passed as a
list or tuple and kwargs as a single dictionary. e.g.:
def fn(**kwargs): print (kwargs) f1(**kwargs)
def f1(**kwargs):
print (len (kwargs))
fn(a = 1 , b= 2 )
# Out:
# {'a': 1, 'b': 2} # 2
sorted ( [" foo " , " bAR" , "BaZ " ], key= lambda s: s.strip().upper()) # Out:
# [' bAR', 'BaZ ', ' foo ']
sorted ( [" foo " , " bAR" , "BaZ " ], key= lambda s: s.strip()) # Out:
# ['BaZ ', ' bAR', ' foo ']
sorted ( map ( lambda s: s.strip().upper(), [" foo " , " bAR" , "BaZ " ])) # Out:
# ['BAR', 'BAZ', 'FOO']
sorted ( map ( lambda s: s.strip(), [" foo " , " bAR" , "BaZ " ])) # Out:
# ['BaZ', 'bAR', 'foo']
my_list = [3 , 4 , 2 , 5 , 1 , 7 ]
sorted ( my_list, key= lambda x: abs (x)) # Out:
# [1, -2, 3, -4, 5, 7]
One can call other functions (with/without arguments) from inside a lambda
function.
def foo(msg): print (msg)
greet = lambda x = "hello world" : foo(x) greet()
prints:
hello world
This is useful because lambda may contain only one expression and by using
a subsidiary function one can run multiple statements.
NOTE
Bear in mind that PEP-8 (the official Python style guide) does not
recommend assigning lambdas to variables (as we did in the first two
examples):
Always use a def statement instead of an assignment statement that binds a
lambda expression directly to an identifier.
Yes:
def f(x): return 2 *x
No:
f = lambda x: 2 *x
The first form means that the name of the resulting function object is
specifically f instead of the generic <lambda> . This is more useful for
tracebacks and string representations in general. The use of the assignment
statement eliminates the sole benefit a lambda expression can offer over an
explicit def statement (i.e. that it can be embedded inside a larger
expression).
Warning
Mutable types ( list , dict , set , etc.) should be treated with care when given
as default attribute. Any mutation of the default argument will change it
permanently. See Defining a function with optional mutable arguments.
For immutable types (see Argument passing and mutability) this is not a
problem because there is no way to mutate the variable; it can only ever be
reassigned, leaving the original value unchanged. Hence, subsequent are
guaranteed to have the same default value. However, for a mutable type, the
original value can mutate, by making calls to its various member functions.
Therefore, successive calls to the function are not guaranteed to have the
initial default value.
# Calling it again without argument will append to the internally stored list
again append(4 )
# Out: [1, 2, 4]
Note: Some IDEs like PyCharm will issue a warning when a mutable type is
specified as a default attribute.
Solution
If you want to ensure that the default argument is always the one you specify
in the function definition, then the solution is to always use an immutable
type as your default argument.
A common idiom to achieve this when a mutable type is needed as the
default, is to use None (immutable) as the default argument and then assign
the actual default value to the argument variable if it is equal to None .
def append(elem, to= None ): if to is None :
to = []
to.append(elem) return to
def foo(x): # here x is the parameter, when we call foo(y) we assign y to x x[0
] = 9 # This mutates the list labelled by both x and y x = [1 , 2 , 3 ] # x is now
labeling a different list (y is unaffected) x[2 ] = 8 # This mutates x's list, not y's
list
x = [3 , 1 , 9 ]
y=x
x.append(5 ) # Mutates the list labelled by x and y, both x and y are bound to
[3, 1, 9] x.sort() # Mutates the list labelled by x and y (in-place sorting) x = x
+ [4 ] # Does not mutate the list (makes a copy for x only, not y) z = x # z is x
([1, 3, 9, 4])
x += [6 ] # Mutates the list labelled by both x and z (uses the extend
function). x = sorted (x) # Does not mutate the list (makes a copy for x only).
x
# Out: [1, 3, 4, 5, 6, 9]
y
# Out: [1, 3, 5, 9]
z
# Out: [1, 3, 5, 9, 4, 6]
Section 33.7: Returning values from functions
num = give_me_five()
print (num) # Print the saved returned value # Out: 5
def give_me_another_five():
return 5
print ('This statement will not be printed. Ever.' )
Closures in Python are created by function calls. Here, the call to makeInc
creates a binding for x that is referenced inside the function inc. Each call to
makeInc creates a new instance of this function, but each instance has a link
to a different binding of x.
def makeInc(x):
def inc(y):
# x is "attached" in the definition of inc
return y + x
return inc
incOne = makeInc(1 ) incFive = makeInc(5 )
incOne(5 ) # returns 6 incFive(5 ) # returns 10
Notice that while in a regular closure the enclosed function fully inherits all
variables from its enclosing environment, in this construct the enclosed
function has only read access to the inherited variables but cannot make
assignments to them
def makeInc(x):
def inc(y):
# incrementing x is not allowed x += y
return x
return inc
incOne = makeInc(1 )
incOne(5 ) # UnboundLocalError: local variable 'x' referenced before
assignment
Python 3 offers the nonlocal statement (Nonlocal Variables ) for realizing a
full closure with nested functions.
Python 3.xVersion ≥ 3.0
def makeInc(x):
def inc(y):
nonlocal x
# now assigning a value to x is allowed x += y
return x
return inc
incOne = makeInc(1 ) incOne(5 ) # returns 6
Section 33.9: Forcing the use of named parameters
All parameters specified after the first asterisk in the function signature are
keyword-only.
def f(*a, b):
pass
f(1 , 2 , 3 )
# TypeError: f() missing 1 required keyword-only argument: 'b'
In Python 3 it's possible to put a single asterisk in the function signature to
ensure that the remaining arguments may only be passed using keyword
arguments.
def f(a, b, *, c): pass
f(1 , 2 , 3 )
# TypeError: f() takes 2 positional arguments but 3 were given
f(1 , 2 , c= 3 ) # No error
Functions in python are first-class objects. They can be defined in any scope
def fibonacci(n):
def step(a, b):
return b, a+b
a, b = 0 , 1
for i in range (n):
a, b = step(a, b)
return a
Functions capture their enclosing scope can be passed around like any other
sort of object
def make_adder(n): def adder(x): return n + x
return adder
add5 = make_adder(5 ) add6 = make_adder(6 ) add5(10 )
#Out: 15
add6(10 )
#Out: 16
return x
repeatedly_apply(add5, 5 , 1 ) #Out: 26
One method for creating recursive lambda functions involves assigning the
function to a variable and then referencing that variable within the function
itself. A common example of this is the recursive calculation of the factorial
of a number - such as shown in the following code:
factorial( 0 ) #out 1
factorial(1 ) #out 1
factorial(2 ) #out 2
factorial(3 ) #out 6
as expected. Notice that this function is recursive because the second return
factorial(n1 ), where the function calls itself in its definition.
Some recursive functions can be implemented using lambda, the factorial
function using lambda would be something like this:
factorial = lambda n: 1 if n == 0 else n*factorial(n1 ) The function outputs the
same as above.
def divide(dividend, divisor): # The names of the function and its arguments
# The arguments are available by name in the body of the function print
(dividend / divisor)
The function name and its list of arguments are called the signature of the
function. Each named argument is effectively a local variable of the function.
When calling the function, give values for the arguments by listing them in
order
divide(10 , 2 ) # output: 5
or specify them in any order using the names from the function definition:
divide(divisor= 2 , dividend= 10 ) # output: 5
>>> unpacking(1 , 2 )
1 2 45 60 () {}
>>> unpacking(1 , 2 , 3 , 4 ) 1 2 3 4 () {}
>>> unpacking(1 , 2 , c= 3 , d= 4 ) 1 2 3 4 () {}
>>> unpacking(1 , 2 , d= 4 , c= 3 ) 1 2 3 4 () {}
>>> pair = (3 , )
>>> unpacking(1 , 2 , *pair, d= 4 )
1 2 3 4 () {}
>>> unpacking(1 , 2 , d= 4 , *pair)
1 2 3 4 () {}
>>> unpacking(1 , 2 , *pair, c= 3 )
Traceback (most recent call last):
>>> args_list = [3 ]
>>> unpacking(1 , 2 , *args_list, d= 4 )
1 2 3 4 () {}
>>> unpacking(1 , 2 , d= 4 , *args_list)
1 2 3 4 () {}
>>> unpacking(1 , 2 , c= 3 , *args_list)
Traceback (most recent call last):
>>> pair = (3 , 4 )
>>> unpacking(1 , 2 , *pair)
1 2 3 4 () {}
>>> unpacking(1 , 2 , 3 , 4 , *pair)
1 2 3 4 (3 , 4 ) {}
>>> unpacking(1 , 2 , d= 4 , *pair)
Traceback (most recent call last):
>>> args_list = [3 , 4 ]
>>> unpacking(1 , 2 , *args_list) 1 2 3 4 () {}
>>> unpacking(1 , 2 , 3 , 4 , *args_list) 1 2 3 4 (3 , 4 ) {}
# Positional arguments take priority over any other form of argument passing
>>> unpacking(1 , 2 , **arg_dict, c= 3 )
1 2 3 4 () {'not_a_parameter' : 75 }
>>> unpacking(1 , 2 , 3 , **arg_dict, c= 3 )
Traceback (most recent call last):
def func(myList):
for item in myList:
print (item)
1
2
3
5
7
Or as a variable:
aList = ['a' , 'b' , 'c' , 'd' ]
func(aList)
a
b
c
d
s= lambda x:x*x
s(2 ) => 4
Let's suppose y can be one of [3,4,5] and let's say you don't want offer end
user the possibility to use such function since it is very computationally
intensive. In fact you would check if provided y assumes a valid value and
rewrite your function as:
What happens here? We fixed the y params and we defined three different
functions.
No need to use the abstract function defined above (you could make it private
) but you could use partial applied functions to deal with raising a number to
a fixed value.
Decorator functions are software design patterns. They dynamically alter the
functionality of a function, method, or class without having to directly use
subclasses or change the source code of the decorated function. When used
correctly, decorators can become powerful tools in the development process.
This topic covers implementation and applications of decorator functions in
Python.
# This simplest decorator does nothing to the function being decorated. Such
# minimal decorators can occasionally be used as a kind of code markers.
def super_secret_function(f):
return f
@ super_secret_function
def my_function():
print ("This is my secret function." )
The @-notation is syntactic sugar that is equivalent to the following:
my_function = super_secret_function(my_function)
def disabled(f):
"""
This function returns nothing, and hence removes the decorated function
from the local scope.
"""
pass
@ disabled
def my_function():
print ("This function can no longer be called..." ) my_function()
# TypeError: 'NoneType' object is not callable
Thus, we usually define a new function inside the decorator and return it. This
new function would first do something that it needs to do, then call the
original function, and finally process the return value. Consider this simple
decorator function that prints the arguments that the original function
receives, then calls it.
print (multiply(3 , 5 ))
#Output:
# (3,5) - This is actually the 'args' that the function receives. # {} - This is the
'kwargs', empty because we didn't specify keyword arguments. # 15 - The
result of the function.
class Decorator(object ):
"""Simple decorator class."""
def __init__ (self , func): self .func = func
def __call__ (self , *args, **kwargs): print ('Before the function call.' ) res =
self .func(*args, **kwargs) print ('After the function call.' ) return res
@ Decorator
def testfunc():
print ('Inside the function.' )
testfunc()
# Before the function call. # Inside the function. # After the function call.
import types
isinstance (testfunc, types .FunctionType) # False
type (testfunc)
# <class '__main__.Decorator'>
Decorating Methods
For decorating methods you need to define an additional __get__ -method:
from types import MethodType
class Decorator(object ): def __init__ (self , func):
self .func = func
def __call__ (self , *args, **kwargs): print ('Inside the decorator.' ) return self
.func(*args, **kwargs)
pass
a = Test()
Inside the decorator.
Warning!
Class Decorators only produce one instance for a specific function so
decorating a method with a class decorator will share the same decorator
between all instances of that class:
from types import MethodType
class CountCallsDecorator(object ):
def __init__ (self , func):
self .func = func
self .ncalls = 0 # Number of calls of this method
a = Test()
a.do_something()
a.do_something.ncalls # 1 b = Test()
b.do_something()
b.do_something.ncalls # 2
return Decorator
@ decoratorfactory(10 ) def test ():
pass
test () Inside the decorator with arguments (10,)
Decorators normally strip function metadata as they aren't the same. This can
cause problems when using metaprogramming to dynamically access
function metadata. Metadata also includes function's docstrings and its name.
functools. wraps makes the decorated function look like the original function
by copying several attributes to the wrapper function.
The two methods of wrapping a decorator are achieving the same thing in
hiding that the original function has been decorated. There is no reason to
prefer the function version to the class version unless you're already using
one over the other.
As a function
def decorator(func):
# Copies the docstring, name, annotations and module to the decorator @
wraps(func)
def wrapped_func(*args, **kwargs):
class Decorator(object ):
def __init__ (self , func):
# Copies name, module, annotations and docstring to the instance. self
._wrapped = wraps(func)(self )
@ Decorator
def test ():
"""Docstring of test."""
pass
t1 = time .time ()
f = func(*args, **kwargs)
t2 = time .time ()
print 'Runtime took {0} seconds' .format(t2-t1) return f
return inner
@ timer
def example_function(): #do stuff
example_function()
def singleton(cls):
instance = [None ]
def wrapper(*args, **kwargs):
if instance[0 ] is None :
instance[0 ] = cls(*args, **kwargs)
return instance[0 ]
return wrapper
This decorator can be added to any class declaration and will make sure that
at most one instance of the class is created. Any subsequent calls will return
the already existing class instance.
@ singleton
class SomeSingletonClass: x = 2
def __init__ (self ): print ("Created!" )
instance.x = 3
print (SomeSingletonClass().x) # 3
So it doesn't matter whether you refer to the class instance via your local
variable or whether you create another "instance", you always get the same
object.
class Person(object ):
"""A simple class.""" # docstring
species = "Homo Sapiens" # class attribute
There are a few things to note when looking at the above example.
>>> # Instances
>>> kelly = Person("Kelly" ) >>> joseph = Person("Joseph" ) >>> john_doe
= Person("John Doe" )
>>> # Attributes
>>> kelly.species 'Homo Sapiens'
>>> john_doe.species 'Homo Sapiens'
>>> joseph.species 'Homo Sapiens'
>>> kelly.name
'Kelly'
>>> joseph.name
'Joseph'
We can execute the methods of the class using the same dot operator .:
>>> # Methods
>>> john_doe.__str__ ()
'John Doe'
>>> print (john_doe)
'John Doe'
>>> john_doe.rename("John" ) 'Now my name is John'
return 2 * x
A.f
# <function A.f at ...> (in Python 3.x)
In Python 2 the behavior was different: function objects within the class were
implicitly replaced with objects of type instancemethod, which were called
unbound methods because they were not bound to any particular class
instance. It was possible to access the underlying function using .__func__
property.
A.f( 1 , 7 )
# Python 2: TypeError: unbound method f() must be called with
# A instance as first argument (got int instance instead) # Python 3: 14
a = A()
A.f(a, 20 )
# Python 2 & 3: 40
The nitty-gritty details are as follows: writing a.f invokes the magic
__getattribute__ method of a, which first checks whether a has an attribute
named f (it doesn't), then checks the class A whether it contains a method
with such a name (it does), and creates a new object m of type method which
has the reference to the original A.f in m.__func__, and a reference to the
object a in m.__self__. When this object is called as a function, it simply does
the following: m(...) => m.__func__(m.__self__, ...). Thus this object is
called a bound method because when invoked it knows to supply the object
it was bound to as the first argument. (These things work same way in Python
2 and 3).
a = A()
a.f
# <bound method A.f of <__main__.A object at ...>> a.f(2 )
#4
# Note: the bound method object a.f is recreated *every time* you call it: a.f
is a.f # False
# As a performance optimization you can store the bound method in the
object's # __dict__, in which case the method object will remain fixed:
a.f = a.f
a.f is a.f # True
Finally, Python has class methods and static methods – special kinds of
methods. Class methods work the same way as regular methods, except that
when invoked on an object they bind to the class of the object instead of to
the object. Thus m.__self__ = type (a). When you call such bound method, it
passes the class of a as the first argument. Static methods are even simpler:
they don't bind anything at all, and simply return the underlying function
without any transformations.
D.f
# <bound method type.f of <class '__main__.D'>> D.f(12 )
# 24
D.g
# <function D.g at ...>
D.g("world" )
# Hello, world
Note that class methods are bound to the class even when accessed on the
instance:
d = D()
d.multiplier = 1337
(D.multiplier, d.multiplier)
# (2, 1337)
d.f
# <bound method D.f of <class '__main__.D'>> d.f(10 )
# 20
The BaseClass is the already existing (parent ) class, and the DerivedClass is
the new (child ) class that inherits (or subclasses ) attributes from BaseClass.
Note : As of Python 2.2, all classes implicitly inherit from the object class ,
which is the base class for all built-in types.
class Rectangle():
def __init__ (self , w, h): self .w = w
self .h = h
def area(self ):
return self .w * self .h
def perimeter(self ):
return 2 * (self .w + self .h)
The Rectangle class can be used as a base class for defining a Square class, as
a square is a special case of rectangle.
class Square(Rectangle):
def __init__ (self , s):
# call parent constructor, w and h are both s super (Square, self ).__init__ (s,
s) self .s = s
The Square class will automatically inherit all attributes of the Rectangle
class as well as the object class. super () is used to call the __init__ () method
of Rectangle class, essentially calling any overridden method of the base
class. Note : in Python 3, super () does not require arguments.
Derived class objects can access and modify the attributes of its base classes:
r.area()
# Output: 12 r.perimeter() # Output: 14
s.area()
# Output: 4
s.perimeter()
# Output: 8
# instantiate
r = Rectangle(3 , 4 ) s = Square(2 )
# Output: False
# A rectangle is not a square
new .__class__
# <class '__main__.New'> type (new )
# <class '__main__.New'> issubclass (New, object ) # True
Old-style classes do not inherit from object . Old-style instances are always
implemented with a built-in instance type.
# old-style class class Old:
pass
# old-style instance old = Old()
old.__class__
# <class __main__.Old at ...> type (old)
# <type 'instance'>
issubclass (Old, object ) # False
type (my_inst)
# <class '__main__.MyClass'> my_inst.__class__
# <class '__main__.MyClass'> issubclass (MyClass, object ) # True
def greet(self ):
print ("Hello, my name is " + self .full_name + "." )
class Person(object ):
def __init__ (self , first_name, age, last_name= None ):
if last_name is None :
self .first_name, self .last_name = first_name.split(" " , 2 )
else :
self .first_name = first_name
self .last_name = last_name
self .full_name = self .first_name + " " + self .last_name self .age = age
def greet(self ):
print ("Hello, my name is " + self .full_name + "." )
However, there are two main problems with this bit of code:
1. The parameters first_name and last_name are now misleading, since you
can enter a full name for first_name. Also, if there are more cases and/or
more parameters that have this kind of flexibility, the if/elif/else branching
can get annoying fast.
2. Not quite as important, but still worth pointing out: what if last_name is
None , but first_name doesn't split into two or more things via spaces? We
have yet another layer of input validation and/or exception handling...
Enter class methods. Rather than having a single initializer, we will create a
separate initializer, called from_full_name, and decorate it with the (built-in)
classmethod decorator.
class Person(object ):
@ classmethod
def from_full_name(cls, name, age):
if " " not in name:
raise ValueError
first_name, last_name = name.split(" " , 2 ) return cls(first_name, last_name,
age)
def greet(self ):
print ("Hello, my name is " + self .full_name + "." )
To show that this works as expected, let's create instances of Person in more
than one way without the branching in __init__ :
In [2 ]: bob = Person("Bob" , "Bobberson" , 42 )
In [3 ]: alice = Person.from_full_name("Alice Henderson" , 31 )
In [4 ]: bob.greet()
Hello, my name is Bob Bobberson.
In [5 ]: alice.greet()
Hello, my name is Alice Henderson.
Other references:
Python @classmethod and @staticmethod for beginner?
https://docs.python.org/2/library/functions.html#classmethod
https://docs.python.org/3.5/library/functions.html#classmethod
class Bar(object ):
foo = 'attr foo of Bar' # we won't see this. bar = 'attr bar of Bar'
That is, for example, Bar cannot inherit from FooBar while FooBar inherits
from Bar.
For a comprehensive example in Python, see the wikipedia entry .
Another powerful feature in inheritance is super . super can fetch parent
classes features.
class Foo(object ):
def foo_method(self ): print "foo Method" class Bar(object ):
def bar_method(self ): print "bar Method" class FooBar(Foo, Bar):
def foo_method(self ):
super (FooBar, self ).foo_method() Multiple inheritance with init method of
class, when every class has own init method then we try for multiple
inheritance then only init method get called of class which is inherit first.
for below example only Foo class init method getting called Bar class init
not getting called
class Foo(object ):
def __init__ (self ): print "foo init" class Bar(object ):
def __init__ (self ): print "bar init"
a = FooBar()
Output:
foobar init foo init
But it doesn't mean that Bar class is not inherit. Instance of final FooBar
class is also instance of Bar class and Foo class.
print isinstance (a, FooBar) print isinstance (a, Foo) print isinstance (a, Bar)
Output:
@ property
def string (self ):
"""A profoundly important string."""
return self ._my_string
@ string .setter
def string (self , new_value):
assert isinstance (new_value, str ), \
"Give me a string, not a %r!" % type (new_value) self ._my_string =
new_value
@ string .deleter
def x(self ):
self ._my_string = None The object's of class MyClass will appear to have a
property .string , however it's behavior is now tightly controlled:
mc = MyClass()
mc.string = "String!" print (mc.string )
del mc.string
As well as the useful syntax as above, the property syntax allows for
validation, or other augmentations to be added to those attributes. This could
be especially useful with public APIs - where a level of help should be given
to the user.
class Character(object ):
def __init__ (name, max_hp): self ._name = name self ._hp = max_hp self
._max_hp = max_hp
@ property
def is_alive(self ): return self .hp != 0 @ property
def is_wounded(self ):
return self .hp < self .max_hp if self .hp > 0 else False @ property
def is_dead(self ):
return not self .is_alive
bilbo.take_damage( 50 )
bilbo.hp # out : 50
bilbo.take_damage( 50 ) bilbo.hp
# out : 0
def area(self ):
return self .width * self .height
class Rectangle2D(object ):
def __init__ (self , width, height, pos= [0 , 0 ], color= 'blue' ): self .width = width
self .height = height
self .pos = pos
self .color = color
r1 = Rectangle2D(5 , 3 )
r2 = Rectangle2D(7 , 8 )
r1.pos[0 ] = 4
r1.pos # [4, 0]
r2.pos # [4, 0] r2's pos has changed as well
This behavior is caused by the fact that in Python default parameters are
bound at function execution and not at function declaration. To get a default
instance variable that's not shared among instances, one should use a
construct like this:
class Rectangle2D(object ):
def __init__ (self , width, height, pos= None , color= 'blue' ): self .width = width
self .height = height
self .pos = pos or [0 , 0 ] # default value is [0, 0] self .color = color
r1 = Rectangle2D(5 , 3 )
r2 = Rectangle2D(7 , 8 )
r1.pos[0 ] = 4
r1.pos # [4, 0]
r2.pos # [0, 0] r2's pos hasn't changed
See also Mutable Default Arguments and “Least Astonishment” and the
Mutable Default Argument .
Instance variables are unique for each instance, while class variables are
shared by all instances.
class C:
x = 2 # class variable
def __init__ (self , y):
self .y = y # instance variable
C.x
#2
C.y
# AttributeError: type object 'C' has no attribute 'y'
c1 = C(3 ) c1.x
#2
c1.y
#3
c2 = C(4 ) c2.x
#2
c2.y
#4
Class variables can be accessed on instances of this class, but assigning to the
class attribute will create an instance variable which shadows the class
variable
c2.x = 4 c2.x
#4
C.x
#2
Note that mutating class variables from instances can lead to some
unexpected consequences.
class D:
x = []
def __init__ (self , item):
d1.x
# [1, 2] d2.x
# [1, 2] D.x
# [1, 2]
def people_in_my_country(self ):
x= sum ([len (c.people) for c in self .city.country.cities]) return x
US = Country()
NYC= City(10 ).join_country(US) SF= City(5 ).join_country(US)
The dir () function can be used to get a list of the members of a class:
dir (Class)
For example:
It is common to look only for "non-magic" members. This can be done using
a simple comprehension that lists members with names not starting with __:
Caveats:
Classes can define a __dir__() method. If that method exists calling dir () will
call __dir__(), otherwise Python will try to create a list of members of the
class. This means that the dir function can have unexpected results. Two
quotes of importance from the official python documentation :
If the object does not provide dir (), the function tries its best to gather
information from the object’s dict attribute, if defined, and from its type
object. The resulting list is not necessarily complete, and may be inaccurate
when the object has a custom getattr ().
it = cls.__it__
except AttributeError :
it = cls.__it__ = object .__new__ (cls) return it
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons. This should
be used as a decorator -- not a metaclass -- to the class that should be a
singleton.
The decorated class can define one `__init__` function that takes only the
`self` argument. Other than that, there are no restrictions that apply to the
decorated class.
To get the singleton instance, use the `Instance` method. Trying to use
`__call__` will result in a `TypeError` being raised.
Limitations: The decorated class cannot be inherited from.
"""
def __init__ (self , decorated): self ._decorated = decorated
def Instance(self ):
"""
Returns the singleton instance. Upon its first call, it creates a new instance of
the decorated class and calls its `__init__` method. On all subsequent calls,
the already created instance is returned.
"""
try : return self ._instance
except AttributeError :
self ._instance = self ._decorated() return self ._instance
x = Single.Instance()
y= Single.Instance()
x.name= 'I \' m single'
x.getName() # outputs I'm single y.getName() # outputs I'm single
These can control the dotted lookup on an instance, and are used to
implement functions, staticmethod , classmethod , and property . A dotted
lookup (e.g. instance foo of class Foo looking up attribute bar - i.e. foo.bar)
uses the following algorithm:
3. look in the class Foo for bar. If it is a Descriptor , then the descriptor
protocol is used. This is how functions (in this context, unbound methods),
classmethod , and staticmethod are implemented. Else it simply returns the
object there, or there is an AttributeError
class mytype(type ):
def __init__ (cls, name, bases, dict ):
# call the base initializer
type .__init__ (cls, name, bases, dict )
When we create a new class using the class keyword the metaclass is by
default chosen based on upon the baseclasses.
>>> class Foo(object ): ... pass
>>> type (Foo) type
In the above example the only baseclass is object so our metaclass will be the
type of object , which is type . It is possible override the default, however it
depends on whether we use Python 2 or Python 3:
Python 2.xVersion ≤ 2.7
A special class-level attribute __metaclass__ can be used to specify the
metaclass.
class MyDummy(object ):
__metaclass__ = mytype
type (MyDummy) # <class '__main__.mytype'>
return cls.__instance
except AttributeError :
cls.__instance = super (SingletonType, cls).__call__ (*args, **kwargs)
return cls.__instance
What is a metaclass?
In Python, everything is an object: integers, strings, lists, even functions and
classes themselves are objects. And every object is an instance of a class.
To check the class of an object x, one can call type (x), so:
>>> type (5 )
< type 'int' >
>>> type (str )
< type 'type' >
>>> type ([1 , 2 , 3 ]) < type 'list' >
Most classes in python are instances of type . type itself is also a class. Such
classes whose instances are also classes are called metaclasses.
The Simplest Metaclass
OK, so there is already one metaclass in Python: type . Can we create another
one?
class SimplestMetaclass(type ): pass
class MyClass(object ):
__metaclass__ = SimplestMetaclass
That does not add any functionality, but it is a new metaclass, see that
MyClass is now an instance of SimplestMetaclass:
>>> type (MyClass)
< class '__main__.SimplestMetaclass' >
A Metaclass which does Something
A metaclass which does something usually overrides type 's __new__ , to
modify some properties of the class to be created, before calling the original
__new__ which creates the class:
class AnotherMetaclass(type ):
def __new__ (cls, name, parents, dct):
# cls is this class
# name is the name of the class to be created
# parents is the list of the class's parent classes
# dct is the list of class's attributes (methods, static variables)
# here all of the attributes can be modified before creating the class, e.g.
dct['x' ] = 8 # now the class will have a static variable x = 8
# return value is the new class. super will take care of that return super
(AnotherMetaclass, cls).__new__ (cls, name, parents, dct)
foo = 1
bar = 'bar'
baz = 3.14
You can use str .format to format output. Bracket pairs are replaced with
arguments in the order in which the arguments are passed:
print ('{}, {} and {}' .format(foo, bar, baz))
# Out: "1, bar and 3.14"
Indexes can also be specified inside the brackets. The numbers correspond to
indexes of the arguments passed to the str .format function (0-based).
class AssignValue(object ):
def __init__ (self , value):
self .value = value
my_value = AssignValue(6 )
print ('My value is: {0.value}' .format(my_value)) # "0" is optional # Out:
"My value is: 6"
Note: In addition to str .format, Python also provides the modulo operator %-
-also known as the string formatting or interpolation operator (see PEP 3101
)--for formatting strings. str .format is a successor of % and it offers greater
flexibility, for instance by making it easier to carry out multiple substitutions.
In addition to argument indexes, you can also include a format specification
inside the curly brackets. This is an expression that follows special rules and
must be preceded by a colon (:). See the docs for a full description of format
specification. An example of format specification is the alignment directive
:~ ^20 (^ stands for center alignment, total width 20, fill with ~ character):
number_list = [12 , 45 , 78 ]
print map ('the number is {}' .format, number_list)
# Out: ['the number is 12', 'the number is 45', 'the number is 78']
fill_char (if omitted default is whitespace) is the character used for the
padding.
'{:~<9s}, World' .format('Hello' ) # 'Hello~~~~, World'
'{:~>9s}, World' .format('Hello' ) # '~~~~Hello, World'
'{:~^9s}' .format('Hello' ) # '~~Hello~~'
'{:0=6d}' .format(123 ) # '-00123'
Note: you could achieve the same results using the string functions ljust(),
rjust(), center(), zfill(), however these functions are deprecated since version
2.5.
This works with more advanced format strings too, including alignment and
dot notation.
>>> f'{foo:^7s}' ' bar '
Note: The f'' does not denote a particular type like b'' for bytes or u'' for
unicode in python2. The formatting is immediately applied, resulting in a
normal string.
The format strings can also be nested :
>>> s = 'Hello'
>>> a, b, c = 1.12345 , 2.34567 , 34.5678 >>> digits = 2
Format strings may contain named placeholders that are interpolated using
keyword arguments to format.
Using a dictionary (Python 2.x)
Any class can configure its own string formatting syntax through the
__format__ method. A type in the standard Python library that makes handy
use of this is the datetime type, where one can use strftime-like formatting
codes directly within str .format:
Some formats can take additional parameters, such as the width of the
formatted string, or the alignment:
>>> '{:.>10}' .format('foo' )
'.......foo'
Those can also be provided as parameters to format by nesting more {} inside
the {}:
>>> data = ["a" , "bbbbbbb" , "ccc" ] >>> m = max (map (len , data))
>>> for d in data:
... print ('{:>{}}' .format(d, m))
a
bbbbbbb
ccc
combined
{:> 3.3 } : 1 : {:3.3 } :1 : {:3.3 } :333 : {:3.3 } :555 :
For every value which is passed to the format function, Python looks for a
__format__ method for that argument. Your own custom class can therefore
have their own __format__ method to determine how the format function will
display and format your class and it's attributes.
This is different than the __str__ method, as in the __format__ method you
can take into account the formatting language, including alignment, field
width etc, and even (if you wish) implement your own format specifiers, and
your own formatting language extensions.1
raise ValueError ('{} format specifier not understood for this object' ,
format_spec[:1 ])
inst = Example(1 , 2 , 3 )
print "{0:>20s}" .format( inst )
# out : (1,2,3)
# Note how the right align and field width of 20 has been honored.
Note:
If your custom class does not have a custom __format__ method and an
instance of the class is passed to the format function, Python2 will always
use the return value of the __str__ method or __repr__ method to determine
what to print (and if neither exist then the default repr will be used), and you
will need to use the s format specifier to format this. With Python3 , to pass
your custom class to the format function, you will need define __format__
method on your custom class.
Python's string type provides many functions that act on the capitalization of
a string. These include:
str .casefold
str .upper
str .lower
str .capitalize
str .title
str .swapcase
With unicode strings (the default in Python 3), these operations are not 1:1
mappings or reversible. Most of these operations are intended for display
purposes, rather than normalization.
Python 3.xVersion ≥ 3.3 str .casefold()
str .casefold creates a lowercase string that is suitable for case insensitive
comparisons. This is more aggressive than str .lower and may modify strings
that are already in lowercase or cause strings to grow in length, and is not
intended for display purposes.
Parameter Description
table It is a lookup table that defines the mapping from one character to
another.
deletecharsA list of characters which are to be removed from the string.
i = 10
f = 1.5
s = "foo"
l = ['a' , 1 , 2 ]
d = {'a' : 1 , 2 : 'foo' }
For reference, Python also supports C-style qualifiers for string formatting.
The examples below are equivalent to those above, but the str .format
versions are preferred due to benefits in flexibility, consistency of notation,
and extensibility:
Three methods are provided that offer the ability to strip leading and trailing
characters from a string: str .strip, str .rstrip and str .lstrip. All three methods
have the same signature and all three return a new string object with
unwanted characters removed.
str .strip([chars])
str .strip acts on a given string and removes (strips) any leading or trailing
characters contained in the argument chars; if chars is not supplied or is None
, all white space characters are removed by default. For example:
>>> " a line with leading and trailing space " .strip() 'a line with leading and
trailing space'
If chars is supplied, all characters contained in it are removed from the string,
which is returned. For example:
>>> ">>> a Python prompt" .strip('> ' ) # strips '>' character and space
character 'a Python prompt'
str .rstrip([chars]) and str .lstrip([chars])
These methods have similar semantics and arguments with str .strip(), their
difference lies in the direction from which they start. str .rstrip() starts from
the end of the string while str .lstrip() splits from the start of the string.
For example, using str .rstrip:
reversed () can be wrapped in a call to '' .join() to make a string from the
iterator.
>>> '' .join(reversed ('hello' )) 'olleh'
While using reversed () might be more readable to uninitiated Python users,
using extended slicing with a step of
-1 is faster and more concise. Here , try to implement it as function:
If sep isn't provided, or is None , then the splitting takes place wherever there
is whitespace. However, leading and trailing whitespace is ignored, and
multiple consecutive whitespace characters are treated the same as a single
whitespace character:
The sep parameter can be used to define a delimiter string. The original string
is split where the delimiter string occurs, and the delimiter itself is discarded.
Multiple consecutive delimiters are not treated the same as a single
occurrence, but rather cause empty strings to be created.
Python's str type also has a method for replacing occurrences of one sub-
string with another sub-string in a given string. For more demanding cases,
one can use re .sub.
str .replace(old , new [ , count]):
str .replace takes two arguments old and new containing the old sub-string
which is to be replaced by the new substring. The optional argument count
specifies the number of replacements to be made:
For example, in order to replace 'foo' with 'spam' in the following string, we
can call str .replace with old = 'foo' and new = 'spam' :
>>> "Make sure to foo your sentence." .replace('foo' , 'spam' ) "Make sure to
spam your sentence."
If the given string contains multiple examples that match the old argument,
all occurrences are replaced with the value supplied in new :
>>> "It can foo multiple examples of foo if you want." .replace('foo' , 'spam' )
"It can spam multiple examples of spam if you want."
unless, of course, we supply a value for count. In this case count occurrences
are going to get replaced:
Python's str type also features a number of methods that can be used to
evaluate the contents of a string. These are str .isalpha, str .isdigit, str
.isalnum, str .isspace. Capitalization can be tested with str .isupper, str
.islower and str .istitle.
str .isalpha
str .isalpha takes no arguments and returns True if the all characters in a
given string are alphabetic, for example:
>>> "Hello World" .isalpha() # contains a space False
>>> "Hello2World" .isalpha() # contains a number False
>>> "HelloWorld!" .isalpha() # contains punctuation False
>>> "HelloWorld" .isalpha()
True
As an edge case, the empty string evaluates to False when used with ""
.isalpha().
str .isupper, str .islower, str .istitle
These methods test the capitalization in a given string.
str .isupper is a method that returns True if all characters in a given string are
uppercase and False otherwise.
False
Conversely, str .islower is a method that returns True if all characters in a
given string are lowercase and False otherwise.
str .istitle returns True if the given string is title cased; that is, every word
begins with an uppercase character followed by lowercase characters.
12345 True True True ?2 ??5 True True True ?²³????? False True True ??
False False True Five False False False
Bytestrings (bytes in Python 3, str in Python 2), only support isdigit, which
only checks for basic ASCII digits.
As with str .isalpha, the empty string evaluates to False .
str .isalnum
This is a combination of str .isalpha and str .isnumeric, specifically it
evaluates to True if all characters in the given string are alphanumeric , that
is, they consist of alphabetic or numeric characters:
Sometimes a string looks “empty” but we don't know whether it's because it
contains just whitespace or no character at all
>>> "" .isspace() False
To cover this case we need an additional test
But the shortest way to test if a string is empty or just contains whitespace
characters is to use strip(with no arguments it removes all leading and trailing
whitespace characters)
>>> not my_str.strip() True
By specifying a different value for start, end we can get a more localized
search and count, for example, if start is equal to 13 the call to:
>>> s.count("sea" , start) 1
is equivalent to:
interstates_lengths = {
5 : (1381 , 2222 ),
19 : (63 , 102 ),
40 : (2555 , 4112 ),
93 : (189 , 305 ),
}
for road, length in interstates_lengths.items():
miles, kms = length
print ('{} -> {} mi. ({} km.)' .format(str (road).rjust(4 ), str (miles).ljust(4 ),
str (kms).ljust(4 )))
40 > 2555 mi. (4112 km.) 19 > 63 mi. (102 km.) 5 > 1381 mi. (2222 km.) 93 >
189 mi. (305 km.)
ljust and rjust are very similar. Both have a width parameter and an optional
fillchar parameter. Any string created by these functions is at least as long as
the width parameter that was passed into the function. If the string is longer
than width alread, it is not truncated. The fillchar argument, which defaults to
the space character ' ' must be a single character, not a multicharacter string.
The ljust function pads the end of the string it is called on with the fillchar
until it is width characters long. The rjust function pads the beginning of the
string in a similar fashion. Therefore, the l and r in the names of these
functions refer to the side that the original string, not the fillchar , is
positioned in the output string.
as with startswith more than one characters can used as the ending sequence:
You can also use a tuple to check if it ends with any of a set of strings
s[0 ] # '\xc2' - meaningless byte (without context such as an encoding) type (s)
# str - even though it's not a useful one w/o having a known encoding
# In Python 3, the default string literal is Unicode; byte array literals need a
leading b
s[0 ] # b'\xc2' - meaningless byte (without context such as an encoding) type
(s) # bytes - now that byte arrays are explicit, Python can show that.
if value == 1 :
# Returns from function as soon as value is 1
print (">>>> Got 1" )
return
Got value 5
Still looping Got value 3
Still looping Got value 1
>>>> Got 1
import module will import a module and then allow you to reference its
objects -- values, functions and classes, for example -- using the
module.name syntax. In the above example, the random module is imported,
which contains the randint function. So by importing random you can call
randint with random .randint.
If your python file main.py is in the same folder as custom.py. You can
import it like this:
import custom
It is also possible to import a function from a module:
To import specific functions deeper down into a module, the dot operator
may be used only on the left side of the import keyword:
from urllib .request import urlopen
In python, we have two ways to call function from top level. One is import
and another is from . We should use import when we have a possibility of
name collision. Suppose we have hello.py file and world.py files having same
function named function. Then import statement will work good.
The keywords and syntax shown above can also be used in combinations:
If you want to import a module that doesn't already exist as a built-in module
in the Python Standard Library nor as a side-package, you can do this by
adding the path to the directory where your module is found to sys . path. This
may be useful where multiple python environments exist on a host.
import sys
sys .path.append("/path/to/directory/containing/your/module" ) import
mymodule
It is important that you append the path to the directory in which mymodule
is found, not the path to the module itself.
This will import all names defined in the math module into the global
namespace, other than names that begin with an underscore (which indicates
that the writer feels that it is for internal use only).
Warning : If a function with the same name was already defined or
imported, it will be overwritten . Almost always importing only specific
names from math import sqrt, ceil is the recommended way :
def sqrt(num):
print ("I don't know what's the square root of {}." .format(num))
sqrt(4 )
# Output: I don't know what's the square root of 4.
Starred imports are only allowed at the module level. Attempts to perform
them in class or function definitions result in a SyntaxError .
def f():
from math import *
and
class A:
from math import *
both fail with: SyntaxError : import * only allowed at module level
from math import sqrt, ceil # Not recommended from math import sqrt #
Recommended from math import ceil
Instead of importing the complete module you can import only specified
names:
from random import randint # Syntax "from MODULENAME import
NAME1[, NAME2[, ...]]" print (randint(1 , 10 )) # Out: 5
from random is needed, because the python interpreter has to know from
which resource it should import a function or class and import randint
specifies the function or class itself.
Another example below (similar to the one above):
from math import pi
print (pi) # Out: 3.14159265359
The following example will raise an error, because we haven't imported a
module:
random .randrange(1 , 10 ) # works only if "import random" has been run
before
Outputs:
NameError: name 'random' is not defined
The python interpreter does not understand what you mean with random . It
needs to be declared by adding import random to the example:
import random
random .randrange(1 , 10 )
When using the interactive interpreter, you might want to reload a module.
This can be useful if you're editing a module and want to import the newest
version, or if you've monkey-patched an element of an existing module and
want to revert your changes.
Note that you can't just import the module again to revert:
import math
math .pi = 3
print (math .pi) # 3
import math
print (math .pi) # 3
This is because the interpreter registers every module you import. And when
you try to reimport a module, the interpreter sees it in the register and does
nothing. So the hard way to reimport is to use import after removing the
corresponding item from the register:
import math
math .pi = 3
print (math .pi) # 3
reload (math )
print (math .pi) # 3.141592653589793
Python 3
The reload function has moved to importlib:
Python 3.xVersion ≥ 3.0
import math
math .pi = 3
print (math .pi) # 3
from importlib import reload
reload (math )
print (math .pi) # 3.141592653589793
A module is a single Python file that can be imported. Using a module looks
like this:
module.py
def hi():
print ("Hello world!" )
my_script.py
import module
module.hi()
in an interpreter
>>> from module import hi
>>> hi()
# Hello world!
__init__ .py
dog.py
hi.py
__init__ .py
from package.dog import woof
from package.hi import hi
dog.py
def woof():
print ("WOOF!!!" )
hi.py
def hi():
print ("Hello world!" )
All Python packages must contain an __init__ .py file. When you import a
package in your script (import package), the __init__ .py script will be run,
giving you access to the all of the functions in the package. In this case, it
allows you to use the package.hi and package.woof functions.
In addition to the built-in round function, the math module provides the floor,
ceil, and trunc functions.
x = 1.55
y = 1.55
# the second argument gives how many decimal places to round to (defaults
to 0) round (x, 1 ) # 1.6
round (y, 1 ) # -1.6
math .asin(1 )
# Out: 1.5707963267948966 # "= pi / 2" math .asin(1 ) / math .pi
# Out: 0.5
In all versions of Python, we can represent infinity and NaN ("not a number")
as follows:
In Python 3.5 and higher, we can also use the defined constants math .inf and
math .nan:
Python 3.xVersion ≥ 3.5
float ('inf' ) is float ('inf' ), float ('nan' ) is float ('nan' ) # Out: (False, False)
math .log can lose precision with numbers close to 1, due to the limitations of
floating-point numbers. In order to accurately calculate logs close to 1, use
math .log1p, which evaluates the natural logarithm of 1 plus the argument:
math .log(1 + 1e-20 ) # 0.0 math .log1p(1e-20 ) # 1e-20
math .log10 can be used for logs base 10:
math .log10(10 ) # 1.0 Python 2.xVersion ≥ 2.3.0
When used with two arguments, math .log(x, base) gives the logarithm of x
in the given base (i.e. log(x) / log(base).
Python 3.5 and higher have constants for infinity and NaN ("not a number").
The older syntax of passing a string to float () still works.
Python 3.xVersion ≥ 3.5 math .inf == float ('inf' ) # Out: True
-math .inf == float ('-inf' ) # Out: True
# NaN never compares equal to anything, even itself math .nan == float ('nan'
# Out: False
z.conjugate()
# Out: (1-3j) # z.conjugate() == z.real - z.imag * 1j
The built-in functions abs and complex are also part of the language itself and
don't require any import:
abs (1 + 1j)
# Out: 1.4142135623730951 # square root of 2
complex (1 )
# Out: (1+0j)
complex (imag= 1 ) # Out: (1j)
complex (1 , 1 ) # Out: (1+1j)
The complex function can take a string, but it can't have spaces:
complex ('1+1j' ) # Out: (1+1j)
complex ('1 + 1j' )
# Exception: ValueError: complex() arg is a malformed string
But for most functions we do need the module, for instance sqrt:
import cmath
cmath .sqrt(1 ) # Out: 1j
Naturally the behavior of sqrt is different for complex numbers and real
numbers. In non-complex math the square root of a negative number raises an
exception:
import math
math .sqrt(1 )
# Exception: ValueError: math domain error
Functions are provided to convert to and from polar coordinates:
cmath .polar(1 + 1j)
# Out: (1.4142135623730951, 0.7853981633974483) # == (sqrt(1 + 1),
atan2(1, 1))
abs (1 + 1j), cmath .phase(1 + 1j)
# Out: (1.4142135623730951, 0.7853981633974483) # same as previous
calculation
cmath .rect(math .sqrt(2 ), math .atan(1 )) # Out:
(1.0000000000000002+1.0000000000000002j)
Square roots:
cmath .sqrt(z) # (1.6741492280355401+0.8959774761298381j)
Trigonometric functions and their inverses:
z + w # (3-4j)
z - w # (1+10j)
z * w # (23-11j)
z / w # (-0.38+0.34j) z**3 # (-46+9j)
Python can also extract the real and imaginary parts of complex numbers, and
calculate their absolute value and conjugate:
z.real # 2.0
z.imag # 3.0
abs (z) # 3.605551275463989 z.conjugate() # (2-3j)
Recipes
>>> c = collections .Counter({'a' : 4 , 'b' : 2 , 'c' : 2 , 'd' : 0 })
Get count of individual element
>>> c['a' ]
4
Set count of individual element
>>> c['c' ] = 3
>>> c
Counter({'a' : 4 , 'b' : 2 , 'd' : 0 , 'c' : 3 })
(The arbitrary ordering implied above means that you may get different
results with the above code to that shown here.)
The order in which the keys appear is the order which they would be iterated
over, e.g. using a for loop.
The collections .OrderedDict class provides dictionary objects that retain the
order of keys. OrderedDicts can be created as shown below with a series of
ordered items (here, a list of tuple key-value pairs):
>>> from collections import OrderedDict
>>> d = OrderedDict([('foo' , 5 ), ('bar' , 6 )]) >>> print (d)
OrderedDict([('foo' , 5 ), ('bar' , 6 )])
>>> d['baz' ] = 7
>>> print (d)
OrderedDict([('foo' , 5 ), ('bar' , 6 ), ('baz' , 7 )]) >>> d['foobar' ] = 8
>>> o = OrderedDict()
>>> o['key1' ] = "value1"
>>> o['key2' ] = "value2"
>>> print (o)
OrderedDict([('key1' , 'value1' ), ('key2' , 'value2' )])
Iterating through an OrderedDict allows key access in the order they were
added.
What happens if we assign a new value to an existing key?
>>> d['foo' ] = 4
>>> print (d)
OrderedDict([('foo' , 4 ), ('bar' , 6 ), ('baz' , 7 ), ('foobar' , 8 )])
returns a reference to a defaultdict that will create a string object with its
default_factory method.
A typical usage of defaultdict is to use one of the builtin types such as str , int
, list or dict as the default_factory, since these return empty types when called
with no arguments:
Calling the defaultdict with a key that does not exist does not produce an
error as it would in a normal dictionary.
>>> state_capitals['Alaska' ]
''
>>> state_capitals
defaultdict(< class 'str' >, {'Alaska' : '' })
0
>>> fruit_counts # A new key is created default_dict(int , {'apple' : 2 , 'banana'
0 })
Using list as the default_factory will create a list for each new key.
{ 'VA' : ['Richmond' ],
'NC' : ['Raleigh' , 'Asheville' ],
'WA' : ['Seattle' ]})
Though list objects support similar operations, they are optimized for fast
fixed-length operations and incur O(n) memory movement costs for pop(0)
and insert(0, v) operations which change both the size and position of the
underlying data representation.
# add a new entry to the right side # add a new entry to the left side >>> d #
show the representation of the deque deque(['f' , 'g' , 'h' , 'i' , 'j' ])
>>> d.pop()
'j'
>>> d.popleft() 'f'
>>> list (d)
['g' , 'h' , 'i' ] >>> d[0 ]
'g'
>>> d[1 ]
'i'
>>> deque(reversed (d)) # make a new deque in reverse order deque(['l' , 'k' , 'j'
'i' , 'h' , 'g' ])
>>> d.clear() # empty the deque
>>> d.pop() # cannot pop from an empty deque Traceback (most recent call
last):
Anytime one has a chain of lookup values there can be a case for ChainMap.
An example includes having both user specified values and a dictionary of
default values. Another example is the POST and GET parameter maps found
in web use, e.g. Django or Flask. Through the use of ChainMap one returns a
combined view of two distinct dictionaries.
# define two dictionaries with at least some keys overlapping. dict1 = {'apple'
: 1 , 'banana' : 2 }
dict2 = {'coconut' : 1 , 'date' : 1 , 'apple' : 3 }
Note the impact of order on which value is found first in the subsequent
lookup
for k, v in combined_dict.items(): print (k, v)
date 1
apple 1 banana 2 coconut 1
date 1
apple 3
banana 2 coconut 1
alist_of_tuples = [(5 , 2 ), (1 , 3 ), (2 , 2 )]
sorted (alist_of_tuples, key= itemgetter(1 , 0 ))
# Output: [(2, 2), (5, 2), (1, 3)]
For every infix operator, e.g. + there is an operator -function (operator .add
for +):
1+1
# Output: 2
from operator import add
add(1 , 1 )
# Output: 2
even though the main documentation states that for the arithmetic operators
only numerical input is allowed it is possible:
See also: mapping from operation to operator function in the official Python
documentation .
The following snippet encodes the data stored in d into JSON and stores it in
a file (replace filename with the actual name of the file).
import json
d={
'foo' : 'bar' ,
'alice' : 1 ,
'wonderland' : [1 , 2 , 3 ]
}
with open (filename, 'w' ) as f:
json.dump(d, f)
The following snippet opens a JSON encoded file (replace filename with the
actual name of the file) and returns the object that is stored in the file.
import json
with open (filename, 'r' ) as f: d = json.load(f)
"cats" : [ {
"name" : "Tubbs" , "color" : "white"
},
{
"name" : "Pepper" , "color" : "black"
}
]
}
Sorting keys alphabetically to get consistent output
By default the order of keys in the output is undefined. We can get them in
alphabetical order to make sure we always get the same output:
>>> print (json.dumps(data, sort_keys= True ))
{"cats" : [{"color" : "white" , "name" : "Tubbs" }, {"color" : "black" , "name"
"Pepper" }]} Getting rid of whitespace to get compact output
We might want to get rid of the unnecessary spaces, which is done by setting
separator strings different from the default ', ' and ': ' :
>>> print (json.dumps(data, separators= (',' , ':' )))
{"cats" :[{"name" :"Tubbs" , "color" :"white" }, {"name" :"Pepper" , "color"
:"black" }]}
The json module contains functions for both reading and writing to and from
unicode strings, and reading and writing to and from files. These are
differentiated by a trailing s in the function name. In these examples we use a
StringIO object, but the same functions would apply for any file-like object.
json_file = StringIO ()
data = {u"foo" : u"bar" , u"baz" : []}
json.dump(data, json_file)
json_file.seek(0 ) # Seek back to the start of the file before reading
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0 ) # Seek back to the start of the file before reading
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
As you can see the main difference is that when dumping json data you must
pass the file handle to the function, as opposed to capturing the return value.
Also worth noting is that you must seek to the start of the file before reading
or writing, in order to avoid data corruption. When opening a file the cursor
is placed at position 0, so the below would also work:
import json
json_file_path = './data.json' data = {u"foo" : u"bar" , u"baz" : []} with open
(json_file_path, 'w' ) as json_file: json.dump(data, json_file)
Having both ways of dealing with json data allows you to idiomatically and
efficiently work with formats which build upon json, such as pyspark's json-
per-line:
# loading from a file
data = [json.loads(line) for line in open (file_path).splitlines()]
# dumping to a file
with open (file_path, 'w' ) as json_file: for item in data:
json.dump(item, json_file) json_file.write(' \n ' )
import json
from datetime import datetime
data = {'datetime' : datetime (2016 , 9 , 26 , 4 , 44 , 0 )}
print (json.dumps(data))
return obj.isoformat()
except AttributeError :
# obj has no isoformat method; let the builtin JSON encoder handle it
return super (DatetimeJSONEncoder, self ).default(obj)
encoder = DatetimeJSONEncoder()
print (encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}
import json
d={
'foo' : 'bar' ,
'alice' : 1 ,
'wonderland' : [1 , 2 , 3 ]
}
json.dumps(d)
The above snippet will return the following: '{"wonderland": [1, 2, 3], "foo":
"bar", "alice": 1}'
import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)
The above snippet will return the following: {u'alice' : 1 , u'foo' : u'bar' ,
u'wonderland' : [1 , 2 , 3 ]}
The sqlite3 module was written by Gerhard Häring. To use the module, you
must first create a Connection object that represents the database. Here the
data will be stored in the example.db file:
import sqlite3
conn = sqlite3.connect('example.db' )
You can also supply the special name :memory: to create a database in RAM.
Once you have a Connection, you can create a Cursor object and call its
execute() method to perform SQL commands:
c = conn.cursor()
# Create table
c.execute('''CREATE TABLE stocks
(date text, trans text, symbol text, qty real, price real)''' )
# Insert a row of data
c.execute("INSERT INTO stocks VALUES ('2006-01-
05','BUY','RHAT',100,35.14)" )
# Save (commit) the changes
conn.commit()
Section 50.2: Getting the values from the database and Error
handling
import sqlite3
conn = sqlite3.connect('example.db' )
c = conn.cursor()
c.execute("SELECT * from table_name where id=cust_id" )
for row in c:
└── dir1
├── subdir1
└── subdir2
We want to create the same subdir1, subdir2 under a new directory dir2,
which does not exist yet.
import os
os .makedirs("./dir2/subdir1" )
os .makedirs("./dir2/subdir2" )
Running this results in
├── dir1
│ ├── subdir1
│ └── subdir2
└── dir2
├── subdir1
└── subdir2
dir2 is only created the first time it is needed, for subdir1's creation.
If we had used os.mkdir instead, we would have had an exception because
dir2 would not have existed yet.
os .mkdir("./dir2/subdir1" )
OSError : [Errno 2 ] No such file or directory: './dir2/subdir1'
os.makedirs won't like it if the target directory exists already. If we re-run it
again:
OSError : [Errno 17 ] File exists: './dir2/subdir1'
However, this could easily be fixed by catching the exception and checking
that the directory has been created.
try :
os .makedirs("./dir2/subdir1" )
except OSError :
if not os .path.isdir("./dir2/subdir1" ):
raise
try :
os .makedirs("./dir2/subdir2" )
except OSError :
posix
nt
ce
java
os .chmod(path, mode)
where mode is the desired permission, in octal.
a = [1 , 2 , 3 , 4 , 5 ]
b = list (itertools .combinations(a, 2 ))
print b
Output:
[(1 , 2 ), (1 , 3 ), (1 , 4 ), (1 , 5 ), (2 , 3 ), (2 , 4 ), (2 , 5 ), (3 , 4 ), (3 , 5 ), (4 , 5 )]
The above output is a generator converted to a list of tuples of all the possible
pair -wise combinations of the input list a
You can also find all the 3-combinations:
a = [1 , 2 , 3 , 4 , 5 ]
b = list (itertools .combinations(a, 3 ))
print b
Output:
[( 1 , 2 , 3 ), (1 , 2 , 4 ), (1 , 2 , 5 ), (1 , 3 , 4 ),
(1 , 3 , 5 ), (1 , 4 , 5 ), (2 , 3 , 4 ), (2 , 3 , 5 ),
(2 , 4 , 5 ), (3 , 4 , 5 )]
if not predicate(x):
yield x
break
for x in iterable:
yield x
The concatenation of results produced by takewhile and dropwhile produces
the original iterable. result = list (itertools .takewhile(is_even, lst)) + list
(itertools .dropwhile(is_even, lst))
x, y = i # Note that zip longest returns the values as a tuple print (x, y)
An optional fillvalue argument can be passed (defaults to '') like so:
print (data)
Normally you cannot slice a generator:
def gen():
n=0
while n < 20 :
n += 1 yield n
for part in gen()[:3 ]: print (part)
Will give
Traceback (most recent call last):
File "gen.py" , line 6 , in < module>
for part in gen()[:3 ]:
TypeError : 'generator' object is not subscriptable
However, this works:
import itertools
def gen():
n=0
while n < 20 :
n += 1 yield n
for part in itertools .islice(gen(), 3 ): print (part)
Note that like a regular slice, you can also use start, stop and step arguments:
itertools .islice(iterable, 1 , 30 , 3 )
def testGroupBy(lst):
groups = itertools .groupby(lst, key= lambda x: x[1 ])
for key, group in groups:
# 5 [('a', 5, 6)]
# 2 [('b', 2, 4), ('a', 2, 5)] # 5 [('c', 5, 6)]
The group returned by groupby is an iterator that will be invalid before next
iteration. E.g the following will not work if you want the groups to be sorted
by key. Group 5 is empty below because when group 2 is fetched it
invalidates 5
# 2 [('c', 2, 6)] # 5 []
To correctly do sorting, create a list from the iterator before sorting
groups = itertools .groupby(lst, key= lambda x: x[1 ])
for key, group in sorted ((key, list (group)) for key, group in groups): print
(key, list (group))
# 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)] # 5 [('a', 5, 6)]
yield x
else :
break
a = [1 , 2 , 3 ]
list (itertools .permutations(a))
# [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
a = [1 , 2 , 1 ]
list (itertools .permutations(a))
# [(1, 2, 1), (1, 1, 2), (2, 1, 1), (2, 1, 1), (1, 1, 2), (1, 2, 1)]
set (itertools .permutations(a)) # {(1, 1, 2), (1, 2, 1), (2, 1, 1)}
Therefore, take care to give boundaries when using this to avoid an infinite
loop. Example:
>>> # Iterate over each element in cycle for a fixed range >>> cycle_iterator =
it.cycle('abc123' )
>>> [next(cycle_iterator) for i in range (0 , 10 )] ['a' , 'b' , 'c' , '1' , '2' , '3' , 'a' , 'b'
0
1
2
3
4
5
6
7
8
9
10
Arguments:
count() takes two arguments, start and step:
break
Output:
10
14
18
22
Results in:
'1 2 3 4 x y z'
As an alternate constructor, you can use the classmethod chain.from_iterable
which takes as its single parameter an iterable of iterables. To get the same
result as above:
' ' .join(chain.from_iterable([a, b])
While chain can take an arbitrary number of arguments, chain.from_iterable
is the only way to chain an infinite number of iterables.
Before Python 3.5+ was released, the asyncio module used generators to
mimic asynchronous calls and thus had a different syntax than the current
Python 3.5 release.
Python 3.xVersion ≥ 3.5
Python 3.5 introduced the async and await keywords. Note the lack of
parentheses around the await func() call.
import asyncio
async def main():
print (await func())
if __name__ == "__main__" :
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
@ asyncio.coroutine
def func():
# Do time intensive stuff..
return "Hello, world!"
if __name__ == "__main__" :
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
await asyncio.sleep(1.5 )
print ("cor1" , i)
await asyncio.sleep(1 )
print ("cor2" , i)
if __name__ == "__main__" :
loop = asyncio.get_event_loop() loop.run_until_complete(main(loop))
Each event loop also has a "default" Executor slot that can be assigned to an
Executor. To assign an Executor and schedule tasks from the loop you use
the set_default_executor() method.
import asyncio
from concurrent.futures import ThreadPoolExecutor
if __name__ == "__main__" :
asyncio.set_event_loop(uvloop.new_event_loop()) # Do your stuff here ...
One can also change the event loop factory by setting the EventLoopPolicy to
the one in uvloop.
import asyncio import uvloop
if __name__ == "__main__" :
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) loop =
asyncio.new_event_loop()
Section 54.4: Synchronization Primitive: Event
Concept
Use an Event to synchronize the scheduling of multiple coroutines .
Put simply, an event is like the gun shot at a running race: it lets the runners
off the starting blocks.
Example
import asyncio
# event consumers
async def consumer_a(event):
consumer_name = 'Consumer A'
print ('{} waiting' .format(consumer_name))
await event.wait()
print ('{} triggered' .format(consumer_name))
# event
event = asyncio.Event()
# wrap coroutines in one future
main_future = asyncio.wait([consumer_a(event), consumer_b(event)])
# event loop
event_loop = asyncio.get_event_loop()
event_loop.call_later(0.1 , functools.partial(trigger, event)) # trigger event in
0.1 sec
# complete main_future
done, pending = event_loop.run_until_complete(main_future)
Output:
if __name__ == '__main__' :
# The main loop
loop = asyncio.get_event_loop() loop.run_until_complete(main())
probably the most common misconception about asnycio is that it lets you
run any task in parallel - sidestepping the GIL (global interpreter lock) and
therefore execute blocking jobs in parallel (on separate threads). it does not !
asyncio (and libraries that are built to collaborate with asyncio) build on
coroutines: functions that (collaboratively) yield the control flow back to the
calling function. note asyncio.sleep in the examples above. this is an example
of a non-blocking coroutine that waits 'in the background' and gives the
control flow back to the calling function (when called with await). time .sleep
is an example of a blocking function. the execution flow of the program will
just stop there and only return after time .sleep has finished.
a real-live example is the requests library which consists (for the time being)
on blocking functions only. there is no concurrency if you call any of its
functions within asyncio. aiohttp on the other hand was built with asyncio in
mind. its coroutines will run concurrently.
if you have long-running CPU-bound tasks you would like to run in parallel
asyncio is not for you. for that you need threads or multiprocessing .
if you have IO-bound jobs running, you may run them concurrently using
asyncio.
In order to create a random user password we can use the symbols provided
in the string module. Specifically punctuation for punctuation symbols,
ascii_letters for letters and digits for digits:
from string import punctuation, ascii_letters, digits
We can then combine all these symbols in a name named symbols:
symbols = ascii_letters + digits + punctuation
Remove either of these to create a pool of symbols with fewer elements.
After this, we can use random .SystemRandom to generate a password. For a
10 length password:
Behind the curtains, these routines use the Mersenne Twister PRNG , which
does not satisfy the requirements of a CSPRNG . Thus, in particular, you
should not use any of them to generate passwords you plan to use. Always
use an instance of SystemRandom as shown above.
import string
alphabet = string .ascii_letters + string .digits
while True :
By default the Python random module use the Mersenne Twister PRNG to
generate random numbers, which, although suitable in domains like
simulations, fails to meet security requirements in more demanding
environments.
# |--sequence--|--number--|
print (random .sample( laughs , 1 )) # Take one element # Out: ['Ho'] #
Output may vary!
Resetting the seed will create the same "random" sequence again:
random .seed(5 ) # Reset the random module to the same fixed state. print
(random .randrange(0 , 10 ))
# Out: 9
print (random .randrange(0 , 10 )) # Out: 4
Since the seed is fixed these results are always 9 and 4. If having specific
numbers is not required only that the values will be the same one can also just
use getstate and setstate to recover to a previous state:
import random
probability = 0.3
In [4 ]: g = partial(f, 1 , 1 , 1 )
In [5 ]: print g(2 ) 1112
When g is created, f, which takes four arguments(a, b, c, x), is also partially
evaluated for the first three arguments, a, b, c, . Evaluation of f is completed
when g is called, g(2 ), which passes the fourth argument to f.
One way to think of partial is a shift register; pushing in one argument at the
time into some function. partial comes handy for cases where data is coming
in as stream and we cannot pass more than one argument.
return n
return fibonacci(n1 ) + fibonacci(n2 )
>>> fibonacci(15 )
maxsize : Number of calls to save. When the number of unique calls exceeds
maxsize, the LRU cache will remove the least recently used calls.
typed (added in 3.3): Flag for determining if equivalent arguments of
different types belong to different cache records (i.e. if 3.0 and 3 count as
different arguments)
In Python 3.x, the reduce function already explained here has been removed
from the built-ins and must now be imported from functools.
from functools import reduce
def factorial(n):
return reduce (lambda a, b: (a*b), range (1 , n+1 ))
# All opcodes in these lists have the respective types as there operands
hascompare = [107 ]
hasconst = [100 ]
hasfree = [135 , 136 , 137 ]
hasjabs = [111 , 112 , 113 , 114 , 115 , 119 ]
hasjrel = [93 , 110 , 120 , 121 , 122 , 143 ]
haslocal = [124 , 125 , 126 ]
hasname = [90 , 91 , 95 , 96 , 97 , 98 , 101 , 106 , 108 , 109 , 116 ]
To disassemble a Python module, first this has to be turned into a .pyc file
(Python compiled). To do this, run
python -m compileall < file> .py
Then in an interpreter, run
import dis
import marshal
altchars
Description
A bytes-like object
If validate is True, the characters not in the normal Base64 alphabet or the
alternative alphabet are not discarded before the padding check
base64 .standard_b64encode(s)
s
base64 .standard_b64decode(s)
s
base64 .urlsafe_b64encode(s)
s
base64 .urlsafe_b64decode(s)
s
b32encode(s)
s
b32decode(s)
s
base64 .b16encode(s)
s
base64 .b16decode(s)
s
ignorechars If adobe is True, the encoded sequenced with be framed with '<~'
and ''~>' as used with Adobe products
The base64 encode and decode functions both require a bytes-like object . To
get our string into bytes, we must encode it using Python's built in encode
function. Most commonly, the UTF8 encoding is used, however a full list of
these standard encodings (including languages with different characters) can
be found here in the official Python Documentation. Below is an example of
encoding a string into bytes:
s = "Hello World!"
b = s.encode("UTF-8" )
The output of the last line would be:
b'Hello World!'
The b prefix is used to denote the value is a bytes object.
To Base64 encode these bytes, we use the base64 .b64encode() function:
import base64
s = "Hello World!"
b = s.encode("UTF-8" ) e = base64 .b64encode(b) print (e)
That code would output the following:
b'SGVsbG8gV29ybGQh'
which is still in the bytes object. To get a string out of these bytes, we can use
Python's decode() method with the UTF8 encoding:
import base64
s = "Hello World!"
b = s.encode("UTF-8" ) e = base64 .b64encode(b) s1 = e.decode("UTF-8" )
print (s1)
import base64
# Creating a string
s = "Hello World!"
# Encoding the string into bytes
b = s.encode("UTF-8" )
# Base64 Encode the bytes
e = base64 .b64encode(b)
# Decoding the Base64 bytes to string
s1 = e.decode("UTF-8" )
# Printing Base64 encoded string
print ("Base64 Encoded:" , s1)
# Encoding the Base64 encoded string into bytes b1 = s1.encode("UTF-8" )
# Decoding the Base64 bytes
d = base64 .b64decode(b1)
# Decoding the bytes to string
s2 = d.decode("UTF-8" )
print (s2)
As you may have expected, the output would be the original string:
Base64 Encoded: SGVsbG8gV29ybGQh Hello World!
import base64
# Creating a string
s = "Hello World!"
# Encoding the string into bytes
b = s.encode("UTF-8" )
# Base32 Encode the bytes
e = base64 .b32encode(b)
# Decoding the Base32 bytes to string
s1 = e.decode("UTF-8" )
# Printing Base32 encoded string
print ("Base32 Encoded:" , s1)
# Encoding the Base32 encoded string into bytes b1 = s1.encode("UTF-8" )
# Decoding the Base32 bytes
d = base64 .b32decode(b1)
# Decoding the bytes to string
s2 = d.decode("UTF-8" )
print (s2)
The base64 module also includes encoding and decoding functions for
Base16. Base 16 is most commonly referred to as hexadecimal . These
functions are very similar to the both the Base64 and Base32 functions:
import base64
# Creating a string
s = "Hello World!"
# Encoding the string into bytes
b = s.encode("UTF-8" )
# Base16 Encode the bytes
e = base64 .b16encode(b)
# Decoding the Base16 bytes to string
s1 = e.decode("UTF-8" )
# Printing Base16 encoded string
print ("Base16 Encoded:" , s1)
# Encoding the Base16 encoded string into bytes b1 = s1.encode("UTF-8" )
# Decoding the Base16 bytes
d = base64 .b16decode(b1)
# Decoding the bytes to string
s2 = d.decode("UTF-8" )
print (s2)
Adobe created its own encoding called ASCII85 which is similar to Base85,
but has its differences. This encoding is used frequently in Adobe PDF files.
These functions were released in Python version 3.4. Otherwise, the functions
base64 .a85encode() and base64 .a85encode() are similar to the previous:
import base64
# Creating a string
s = "Hello World!"
# Encoding the string into bytes
b = s.encode("UTF-8" )
# ASCII85 Encode the bytes
e = base64 .a85encode(b)
# Decoding the ASCII85 bytes to string
s1 = e.decode("UTF-8" )
# Printing ASCII85 encoded string
print ("ASCII85 Encoded:" , s1)
# Encoding the ASCII85 encoded string into bytes b1 = s1.encode("UTF-8" )
# Decoding the ASCII85 bytes
d = base64 .a85decode(b1)
# Decoding the bytes to string
s2 = d.decode("UTF-8" )
print (s2)
This outputs the following:
ASCII85 Encoded: 87cURD]i,"Ebo80 Hello World!
import base64
# Creating a string
s = "Hello World!"
# Encoding the string into bytes
b = s.encode("UTF-8" )
# Base85 Encode the bytes
e = base64 .b85encode(b)
# Decoding the Base85 bytes to string
s1 = e.decode("UTF-8" )
# Printing Base85 encoded string
print ("Base85 Encoded:" , s1)
# Encoding the Base85 encoded string into bytes b1 = s1.encode("UTF-8" )
# Decoding the Base85 bytes
d = base64 .b85decode(b1)
# Decoding the bytes to string
s2 = d.decode("UTF-8" )
print (s2)
for x in range (1 , 10 ):
temp_dict = ('key' , x)
question_queue.put(temp_dict)
Output:
d = deque([1 , 2 , 3 ])
p = d.popleft() # p = 1, d = deque([2, 3])
d.appendleft(5 ) # d = deque([5, 2, 3])
# The oldest seen (but not yet visited) node will be the left most one.
current = q.popleft()
for neighbor in graph[current]:
return distances
Say we have a simple directed graph:
graph = {1 :[2 , 3 ], 2 :[4 ], 3 :[4 , 5 ], 4 :[3 , 5 ], 5 :[]}
We can now find the distances from some starting position:
>>> bfs(graph, 1 )
{1 : 0 , 2 : 1 , 3 : 1 , 4 : 2 , 5 : 2 }
>>> bfs(graph, 3 ) {3 : 0 , 4 : 1 , 5 : 1 }
Details
browser name
path to the executable browser (help )
An instance of a web browser returned from the webbrowser .get() method
If a browser window is currently open, the method will open a new tab at the
specified URL. If no window is open, the method will open the operating
system's default browser and navigate to the URL in the parameter. The open
method supports the following parameters:
Note, the new and autoraise arguments rarely work as the majority of modern
browsers refuse these commands.
Webbrowser can also try to open URLs in new windows with the open_new
method:
import webbrowser
webbrowser .open_new("http://stackoverflow.com" )
This method is commonly ignored by modern browsers and the URL is
usually opened in a new tab. Opening a new tab can be tried by the module
using the open_new_tab method:
import webbrowser
webbrowser .open_new_tab("http://stackoverflow.com" )
The webbrowser module also supports different browsers using the register()
and get() methods. The get method is used to create a browser controller
using a specific executable's path and the register method is used to attach
these executables to preset browser types for future use, commonly when
multiple browser types are used.
import webbrowser
ff_path = webbrowser .get("C:/Program Files/Mozilla Firefox/firefox.exe" ) ff
= webbrowser .get(ff_path)
ff.open ("http://stackoverflow.com/" )
import webbrowser
ff_path = webbrowser .get("C:/Program Files/Mozilla Firefox/firefox.exe" ) ff
= webbrowser .get(ff_path)
webbrowser .register('firefox' , None , ff)
# Now to refer to use Firefox in the future you can use this webbrowser
.get('firefox' ).open ("https://stackoverflow.com/" )
class PlaceExample(Frame):
def __init__ (self , master):
Frame.__init__ (self , master)
self .grid()
top_text= Label(master, text= "This is on top at the origin" )
#top_text.pack()
top_text.place(x= 0 , y= 0 , height= 50 , width= 200 )
bottom_right_text= Label(master, text= "This is at position 200,400" )
#top_text.pack()
bottom_right_text.place(x= 200 , y= 400 , height= 50 , width= 200 )
# Spawn Window
if __name__== "__main__" :
root= Tk()
place_frame= PlaceExample(root)
place_frame.mainloop()
Pack
widget.pack can take the following keyword arguments:
Grid
The most commonly used keyword arguments of widget.grid are as follows:
row , the row of the widget (default smallest unoccupied) rowspan, the
number of columns a widget spans (default 1) column, the column of the
widget (default 0)
columnspan, the number of columns a widget spans (default 1)
sticky, where to place widget if the grid cell is larger than it (combination of
N,NE,E,SE,S,SW,W,NW)
The rows and columns are zero indexed. Rows increase going down, and
columns increase going right.
A code example using grid:
from tkinter import *
class GridExample(Frame):
def __init__ (self , master):
Frame.__init__ (self , master)
self .grid()
top_text= Label(self , text= "This text appears on top left" )
top_text.grid() # Default position 0, 0
bottom_text= Label(self , text= "This text appears on bottom left" )
bottom_text.grid() # Default position 1, 0
right_text= Label(self , text= "This text appears on the right and spans both
rows" ,
wraplength = 100 )
# Position is 0,1
# Rowspan means actual position is [0-1],1
right_text.grid(row= 0 , column= 1 , rowspan= 2 )
# Spawn Window
if __name__== "__main__" :
root= Tk()
grid_frame= GridExample(root)
grid_frame.mainloop()
Never mix pack and grid within the same frame! Doing so will lead to
application deadlock!
# Spawn window
if __name__ == "__main__" : # Create main window object
root = tk.Tk()
# Set title of window
root.title("Hello World!" )
# Instantiate HelloWorldFrame object hello_frame = HelloWorldFrame(root)
# Start GUI
hello_frame.mainloop()
typewrite( '' ) #this will type the string on the screen where current window
has focused. typewrite(['a' , 'b' , 'left' , 'left' , 'X' , 'Y' ])
pyautogui.KEYBOARD_KEYS #get the list of all the keyboard_keys.
pyautogui.hotkey('ctrl' , 'o' ) #for the combination of keys to enter.
start is the first index of the slice. Defaults to 0 (the index of the first element)
stop one past the last index of the slice. Defaults to len(iterable)
step is the step size (better explained by the examples below)
Examples:
a = "abcdef"
a # "abcdef"
# Same as a[:] or a[::] since it uses the defaults for all three indices a[1 ] #
"f"
a[:] # "abcdef"
a[::] # "abcdef"
a[3 :] # "def" (from index 3, to end(defaults to size of iterable)) a[:4 ] #
"abcd" (from beginning(default 0) to position 4 (excluded)) a[2 :4 ] # "cd"
(from position 2, to position 4 (excluded))
In addition, any of the above can be used with the step size defined:
a[::2 ] # "ace" (every 2nd element)
a[1 :4 :2 ] # "bd" (from index 1, to index 4 (excluded), every 2nd element)
Indices can be negative, in which case they're computed from the end of the
sequence
a[:1 ] # "abcde" (from index 0 (default), to the second last element (last
element - 1)) a[:2 ] # "abcd" (from index 0 (default), to the third last element
(last element -2)) a[1 :] # "f" (from the last element to the end (default len())
Step sizes can also be negative, in which case slice will iterate through the list
in reverse order:
a[3 :1 :1 ] # "dc" (from index 2 to None (default), in reverse order)
This construct is useful for reversing an iterable
a[::1 ] # "fedcba" (from last element (default len()-1), to first, in reverse
order(-1))
Notice that for negative steps the default end_index is None (see
http://stackoverflow.com/a/12521981 )
a[5 :None :1 ] # "fedcba" (this is equivalent to a[::-1])
a[5 :0 :1 ] # "fedcb" (from the last element (index 5) to second element (index
1)
You can use slices to very easily reverse a str , list , or tuple (or basically any
collection object that implements slicing with the step parameter). Here is an
example of reversing a string, although this applies equally to the other types
listed above:
s = 'reverse me!'
s[::1 ] # '!em esrever'
Let's quickly look at the syntax. [::1 ] means that the slice should be from the
beginning until the end of the string (because start and end are omitted) and a
step of -1 means that it should move through the string in reverse.
lst = [1 , 2 , 3 ]
lst[1 :3 ] = [4 , 5 ]
print (lst) # Out: [1, 4, 5]
lst = [1 , 2 , 3 , 4 , 5 ]
lst[1 :4 ] = [6 ]
print (lst) # Out: [1, 6, 5]
It's also possible to use the known slicing syntax to do things like replacing
the entire list:
lst = [1 , 2 , 3 ]
lst[:] = [4 , 5 , 6 ]
print (lst) # Out: [4, 5, 6]
lst = [1 , 2 , 3 ]
lst[2 :] = [4 , 5 , 6 ]
print (lst) # Out: [1, 4, 5, 6]
Let's examine the syntax. [:] means that start, end, and slice are all omitted.
They default to 0, len (arr), and 1, respectively, meaning that subarray that we
are requesting will have all of the elements of arr from the beginning until the
very end.
As you can see, arr.append('d' ) added d to arr, but copy remained unchanged!
Note that this makes a shallow copy, and is identical to arr.copy ().
class MultiIndexingList:
def __init__ (self , value): self .value = value
a = MultiIndexingList([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]) a
# Out: [1, 2, 3, 4, 5, 6, 7, 8]
a[ 1 , 5 , 2 , 6 , 1 ]
# Out: [2, 6, 3, 7, 2]
a[4 , 1 , 5 :, 2 , ::2 ]
# Out: [5, 2, [6, 7, 8], 3, [1, 3, 5, 7]]
# 4|1-|----50:---|2-|-----::2----- <-- indicated which element came from which
index
While setting and deleting elements only allows for comma separated integer
indexing (no slicing):
a[ 4 ] = 1000
a
# Out: [1, 2, 3, 4, 1000, 6, 7, 8] a[2 , 6 , 1 ] = 100
a
# Out: [1, 100, 100, 4, 1000, 6, 100, 8] del a[5 ]
a
# Out: [1, 100, 100, 4, 1000, 100, 8] del a[4 , 2 , 5 ]
a
# Out: [1, 100, 4, 8]
You can access the second element in the list by index 1, third element by
index 2 and so on:
You can also use negative indices to access elements from the end of the list.
eg. index -1 will give you the last element of the list and index -2 will give
you the second-to-last element of the list:
If you try to access an index which is not present in the list, an IndexError
will be raised:
print arr[6 ]
Traceback (most recent call last): File "<stdin>" , line 1 , in < module>
IndexError : list index out of range
Chapter 65: Plotting with Matplotlib
Matplotlib ( https://matplotlib.org/) is a library for 2D plotting based on
NumPy. Here are some basic examples. More examples can be found in the
official documentation (https://matplotlib.org/2.0.2/gallery.html and
https://matplotlib.org/2.0.2/examples/index.html)
In this example, we will plot a sine curve and a hyperbolic sine curve in the
same plot with a common x-axis having different y-axis. This is
accomplished by the use of twinx() command.
# Note:
# Grid for second curve unsuccessful : let me know if you find it! :(
import numpy as np
import matplotlib.pyplot as plt
In this example, a plot with curves having common y-axis but different x-axis
is demonstrated using twiny() method. Also, some additional features such as
the title, legend, labels, grids, axis ticks and colours are added to the plot.
import numpy as np
import matplotlib.pyplot as plt
# plot the curves on axes 1, and 2, and get the axes handles curve1, =
ax1.plot(x1, y, label= "sin" , color= 'r' ) curve2, = ax2.plot(x2, y, label= "sinh"
color= 'b' )
# Make a curves list to access the parameters in the curves curves = [curve1,
curve2]
# set x ticks
ax1.set_xticks(xnumbers1) ax2.set_xticks(xnumbers2)
# set y ticks
ax1.set_yticks(ynumbers)
# ax2.set_yticks(ynumbers) # also works
# Grids via axes 1 # use this if axes 1 is used to # define the properties of
common x axis
# ax1.grid(color=curve1.get_color())
plt.plot(x, y)
import numpy as np
import matplotlib.pyplot as plt
Similar to the previous example, here, a sine and a cosine curve are plotted
on the same figure using separate plot commands. This is more Pythonic and
can be used to get separate handles for each plot.
import numpy as np
import matplotlib.pyplot as plt
import pydotplus
graph_a = pydotplus.graph_from_dot_file('demo.dot' )
graph_a.write_svg('test.svg' ) # generate graph in svg.
Generator functions are similar to regular functions, except that they have
one or more yield statements in their body. Such functions cannot return any
values (however empty return s are allowed if you want to stop the generator
early).
def function():
for x in range (10 ):
yield x**2
This generator function is equivalent to the previous generator expression, it
outputs the same.
Note : all generator expressions have their own equivalent functions, but not
vice versa.
A generator expression can be used without parentheses if both parentheses
would be repeated otherwise:
Instead of:
But not:
Notice that a generator's body is not immediately executed: when you call
function() in the example above, it immediately returns a generator object,
without executing even the first print statement. This allows generators to
consume less memory than functions that return a list, and it allows creating
generators that produce infinitely long sequences.
For this reason, generators are often used in data science, and other contexts
involving large amounts of data. Another advantage is that other code can
immediately use the values yielded by a generator, without waiting for the
complete sequence to be produced.
However, if you need to use the values produced by a generator more than
once, and if generating them costs more than storing, it may be better to store
the yielded values as a list than to re-generate the sequence. See 'Resetting a
generator' below for more details.
# Output:
# Received 0
# Received 1
# Received 4
# Received 9
# Received 16 # Received 25 # Received 36 # Received 49 # Received 64 #
Received 81
Since generator objects are iterators, one can iterate over them manually
using the next () function. Doing so will return the yielded values one by one
on each subsequent invocation.
Under the hood, each time you call next() on a generator, Python executes
statements in the body of the generator function until it hits the next yield
statement. At this point it returns the argument of the yield command, and
remembers the point where that happened. Calling next() once again will
resume execution from that point and continue until the next yield statement.
If Python reaches the end of the generator function without encountering any
more yield s, a StopIteration exception is raised (this is normal, all iterators
behave in the same way).
g3 = function()
a = next(g3) # a becomes 0
b = next(g3) # b becomes 1
c = next(g3) # c becomes 2
...
j = next(g3) # Raises StopIteration, j remains undefined
Note that in Python 2 generator objects had .next() methods that could be
used to iterate through the yielded values manually. In Python 3 this method
was replaced with the .__next__() standard for all iterators.
Resetting a generator
Remember that you can only iterate through the objects generated by a
generator once . If you have already iterated through the objects in a script,
any further attempt do so will yield None .
If you need to use the objects generated by a generator more than once, you
can either define the generator function again and use it a second time, or,
alternatively, you can store the output of the generator function in a list on
first use. Re-defining the generator function will be a good option if you are
dealing with large volumes of data, and storing a list of all data items would
take up a lot of disc space. Conversely, if it is costly to generate the items
initially, you may prefer to store the generated items in a list so that you can
re-use them.
def integers_starting_from(n):
while True :
yield n
n += 1
natural_numbers = integers_starting_from(1 )
Infinite sequence of numbers as above can also be generated with the help of
itertools . count. The above code could be written as below
natural_numbers = itertools .count(1 )
You can use generator comprehensions on infinite generators to produce new
generators:
multiples_of_two = (x * 2 for x in natural_numbers) multiples_of_three = (x
for x in natural_numbers if x % 3 == 0 )
Be aware that an infinite generator does not have an end, so passing it to any
function that will attempt to consume the generator entirely will have dire
consequences :
list (multiples_of_two) # will never terminate, or raise an OS-specific error
Instead, use list/set comprehensions with range (or xrange for python < 3.0):
first_five_multiples_of_three = [next(multiples_of_three) for _ in range (5 )]
# [3, 6, 9, 12, 15]
or use itertools . islice() to slice the iterator to a subset:
Note that the original generator is updated too, just like all other generators
coming from the same "root":
next(natural_numbers) # yields 16
next(multiples_of_two) # yields 34
next(multiples_of_four) # yields 24
An infinite sequence can also be iterated with a for -loop. Make sure to
include a conditional break statement so that the loop would terminate
eventually:
break # stop after taking the first 10 multiplies of two Classic example -
Fibonacci numbers import itertools
def fibonacci():
a, b = 1 , 1
while True :
yield a
a, b = b, a + b
first_ten_fibs = list (itertools .islice(fibonacci(), 10 )) # [1, 1, 2, 3, 5, 8, 13, 21,
34, 55]
def nth_fib(n):
return next(itertools .islice(fibonacci(), n - 1 , n)) ninety_nineth_fib =
nth_fib(99 ) # 354224848179261915075
def accumulator():
total = 0
value = None
while True :
# receive sent value value = yield total if value is None : break # aggregate
values total += value
generator = accumulator()
# advance until the first "yield" next(generator) # 0
When you first call next(generator), the program advances to the first yield
statement, and returns the value of total at that point, which is 0. The
execution of the generator suspends at this point. When you then call
generator.send(x), the interpreter takes the argument x and makes it the return
value of the last yield statement, which gets assigned to value. The generator
then proceeds as usual, until it yields the next value.
When you finally call next(generator), the program treats this as if you're
sending None to the generator. There is nothing special about None ,
however, this example uses None as a special value to ask the generator to
stop.
def foob(x):
yield from range (x * 2 )
yield from range (2 )
def fibto(n):
a, b = 1 , 1
while True :
def usefib():
yield from fibto(10 ) yield from fibto(20 )
A generator object supports the iterator protocol . That is, it provides a next()
method (__next__() in Python 3.x), which is used to step through its
execution, and its __iter__ method returns itself. This means that a generator
can be used in any language construct which supports generic iterable
objects.
# naive partial implementation of the Python 2.x xrange() def xrange (n):
i=0
while i < n:
yield i
i += 1
# looping
for i in xrange (10 ):
print (i) # prints the values 0, 1, ..., 9 # unpacking
a, b, c = xrange (3 ) # 0, 1, 2
# building a list
l = list (xrange (10 )) # [0, 1, ..., 9]
def nums():
yield 1
yield 2
yield 3
generator = nums()
next(generator , None ) # 1
next(generator, None ) # 2
next(generator, None ) # 3
next(generator, None ) # None next(generator, None ) # None # ...
The syntax is next(iterator[, default]). If iterator ends and a default value was
passed, it is returned. If no default was provided, StopIteration is raised.
cr = func(*args, **kwargs)
next(cr)
return cr
return start
while True :
x = yield sum sum += x
values = create()
When it's not practical to replace the inner logic with a list comprehension,
you can turn the entire function into a generator in-place, and then collect the
results:
def create_gen():
# logic...
yield value
# more logic
return # not needed if at the end of the function, of course
def preorder_traversal(node):
yield node.value
for child in node.children:
def get_files(path):
for file in listdir(path): full_path = join(path, file ) if isfile(full_path):
if exists(full_path): yield full_path
Another helper function to get only the subdirectories:
def get_directories(path):
for directory in listdir(path): full_path = join(path, directory) if not
isfile(full_path):
def get_files_recursive(directory):
yield from get_files(directory)
for subdirectory in get_directories(directory):
next(generator) # 0
next(generator) # 2
next(generator) # 4
next(generator) # raises StopIteration
def fib(a= 0 , b= 1 ):
"""Generator that yields Fibonacci numbers. `a` and `b` are the seed
values""" while True :
yield a
a, b = b, a + b
f = fib()
print (', ' .join(str (next(f)) for _ in range (10 ))) 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
1x
2y
3z
In python 2 you should use itertools .izip instead. Here we can also see that
the all the zip functions yield tuples.
Note that zip will stop iterating as soon as one of the iterables runs out of
items. If you'd like to iterate for as long as the longest iterable, use itertools
.zip_longest().
Details
function that is used for reducing the iterable (must take two arguments).
(positional-only ) iterable that's going to be reduced. (positional-only )
import operator
reduce (operator .add, asequence) # Out: 6
return s1 * s2
asequence = [1 , 2 , 3 ]
Given an initializer the function is started by applying it to the initializer and
the first iterable element:
Without initializer parameter the reduce starts by applying the function to the
first two list elements:
import operator
reduce (operator .mul, [10 , 5 , 3 ])
# Out: -150
import operator
# non short-circuit "all"
reduce (operator .and_, [False , True , True , True ]) # = False
Details
function for mapping (must take as many parameters as there are iterables)
(positional-only ) the function is applied to each element of the iterable
(positional-only )
The map function is the simplest one among Python built-ins used for
functional programming. map () applies a specified function to each element
in an iterable:
names = ['Fred' , 'Wilma' , 'Barney' ]
Alternatively, in Python 2 one can use imap from itertools to get a generator
Python 2.xVersion ≥ 2.3
map (len , names) # map() returns a list # Out: [4, 5, 6]
image2 = [[1 , 2 , 3 ],
[4 , 5 ],
[7 , 8 , 9 ]]
Series mapping
In this case each argument of the iterable is supplied as argument to the
mapping function in ascending order. This arises when we have just one
iterable to map and the mapping function requires a single argument.
Example 1
results in
['fly is an insect' , 'ant is an insect' , 'beetle is an insect' , 'cankerworm is an insect'
]
Example 2
print (list (map (len , insects))) # the len function is executed each item in the
insect list
results in
[ 3 , 3 , 6 , 10 ]
Parallel mapping
In this case each argument of the mapping function is pulled from across all
iterables (one from each iterable) in parallel. Thus the number of iterables
supplied must match the number of arguments required by the function.
results in
TypeError : len () takes exactly one argument (4 given)
Example 4
# Too few arguments
# observe here that map is supposed to execute animal on individual elements
of insects one-by-one. But animals complain when
# it only gets one argument, whereas it was expecting four.
print (list (map (animals, insects)))
results in
TypeError : animals() missing 3 required positional arguments: 'x' , 'y' , and 'z'
Example 5
# here map supplies w, x, y, z with one value from across the list import pprint
pprint .pprint (list (map (animals, insects, carnivores, herbivores,
omnivores)))
results in
[ 'Fly, lion, african buffalo, and chicken ARE ALL ANIMALS' , 'Ant, tiger,
moose, and dove ARE ALL ANIMALS' ,
'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS' , 'Cankerworm,
arctic fox, parakeet, and pig ARE ALL ANIMALS' ]
import operator
operator .pow (4 , 2 ) # 16
operator .__pow__ (4 , 3 ) # 64
val1 , val2 = 4 , 2
val1.__pow__ (val2) # 16
val2.__rpow__ (val1) # 16
# in-place power operation isn't supported by immutable classes like int,
float, complex: # val1.__ipow__(val2)
The math .sqrt() function raises a ValueError if the result would be complex :
math .sqrt(10 )
ValueError: math domain error
math .sqrt(x) is faster than math .pow (x, 0.5 ) or x ** 0.5 but the precision of
the results is the same. The cmath module is extremely similar to the math
module, except for the fact it can compute complex numbers and all of its
results are in the form of a + bi. It can also use .sqrt():
import cmath
cmath .sqrt(4 ) # 2+0j cmath .sqrt(4 ) # 2j
What's with the j? j is the equivalent to the square root of -1. All numbers can
be put into the form a + bi, or in this case, a + bj. a is the real part of the
number like the 2 in 2 +0j. Since it has no imaginary part, b is 0. b represents
part of the imaginary part of the number like the 2 in 2j. Since there is no real
part in this, 2j can also be written as 0 + 2j.
# steps:
3 ** 4 # 81
81 % 17 # 13
upper_bound * = 2
lower_bound = upper_bound // 2
# Keep searching for a better result as long as the bounds make sense. while
lower_bound < upper_bound:
lower_bound = mid
elif upper_bound > mid and mid_nth > x:
upper_bound = mid
else :
# Found perfect nth root.
return mid
return mid + 1
x = 2 ** 100
cube = x ** 3
root = nth_root(cube, 3 ) x == root
# True
import math
math .pow (2 , 2 ) # 4.0
math .pow (2 ., 2 ) # 4.0
import cmath
cmath .e ** 2 # 7.3890560989306495 cmath .exp(2 ) #
(7.38905609893065+0j)
However the result is different and using the exponential function directly is
more reliable than builtin exponentiation with base math .e:
else :
print ('Using __pow__ with modulo' )
return self .__class__(pow (self .value, other, modulo))
def __complex__(self ):
print ('Using __complex__' ) return complex (self .value, 0 )
Integer( 2 ) ** 2
# Prints: Using __pow__ Integer(2 ) ** 2.5
# Prints: Using __pow__ pow (Integer(2 ), 0.5 )
# Prints: Using __pow__ operator .pow (Integer(2 ), 3 ) # Prints: Using
__pow__ # Integer(4)
# Integer(5)
# Integer(1)
# Integer(8)
operator .__pow__ (Integer(3 ), 3 ) # Integer(27) # Prints: Using __pow__
The second argument of the __pow__ () method can only be supplied by
using the builtinpow () or by directly calling the method:
While the math -functions always convert it to a float and use the float-
computation:
cmath -functions try to convert it to complex but can also fallback to float if
there is no explicit conversion to complex :
import cmath
cmath .exp(Integer(2 )) # (7.38905609893065+0j) # Prints: Using
__complex__
del Integer.__complex__ # Deleting __complex__ method - instances cannot
be cast to complex
cmath .exp(Integer(2 )) # (7.38905609893065+0j) # Prints: Using __float__
Neither math nor cmath will work if also the __float__ ()-method is missing:
del Integer.__float__ # Deleting __complex__ method
math .sqrt(Integer(2 )) # also cmath.exp(Integer(2)) TypeError: a float is
required
>>> x = 3
>>> y = x ** 3
>>> y
27
>>> z = y ** (1.0 / 3 )
>>> z
3.0
>>> z == x
True
alist = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
5 in alist # True
10 in alist # False
Tuple
String
Set
Dict
dict is a bit special: the normal in only checks the keys . If you want to search
in values you need to specify it. The same if you want to search for key-value
pairs.
class ListList:
def __init__ (self , value):
self .value = value
# Even without the set you could use the iter method for the contains-check: #
return any(item == value for item in iter(self))
Using membership testing is possible using in:
Note: The looping in (as in for i in a) will always use __iter__ even if the
class implements a __contains__ method.
astring.find('o' ) # 4 astring.rfind('o' ) # 20
The difference between index/rindex and find/rfind is what happens if the
substring is not found in the string:
astring.index('q' ) # ValueError: substring not found astring.find('q' ) # -1
All of these methods allow a start and end index:
astring.index( 'o' , 5 ) # 6
astring.index('o' , 6 ) # 6 - start is inclusive astring.index('o' , 5 , 7 ) # 6
astring.index('o' , 5 , 6 ) # - end is not inclusive
alist.index(15 )
ValueError: 15 is not in list
But only returns the position of the first found element:
return i
raise ValueError
alist = [i for i in range (1 , 100000 , 3 )] # Sorted list from 1 to 100000 with step
3 index_sorted(alist, 97285 ) # 32428
index_sorted(alist, 4 ) # 1
index_sorted(alist, 97286 )
ValueError
For very large sorted sequences the speed gain can be quite high. In case for
the first search approximately 500 times as fast:
While it's a bit slower if the element is one of the very first:
% timeit index_sorted(alist, 4 )
# 100000 loops, best of 3: 2.98 µ s per loop %timeit alist.index(4 )
# 1000000 loops, best of 3: 580 ns per loop
min , max , and sorted all need the objects to be orderable. To be properly
orderable, the class needs to define all of the 6 methods __lt__ , __gt__ ,
__ge__ , __le__ , __ne__ and __eq__ :
class IntegerContainer(object ):
def __init__ (self , value):
self .value = value
But sorted can use __gt__ instead if the default is not implemented:
del IntegerContainer.__lt__ # The IntegerContainer no longer implements
"less than"
res = min (alist)
# Out: IntegerContainer(5) - Test greater than IntegerContainer(3) #
IntegerContainer(3) - Test greater than IntegerContainer(10) #
IntegerContainer(3) - Test greater than IntegerContainer(7) print (res)
# Out: IntegerContainer(3)
Sorting methods will raise a TypeError if neither __lt__ nor __gt__ are
implemented:
del IntegerContainer.__gt__ # The IntegerContainer no longer implements
"greater then"
res = min (alist)
TypeError: unorderable types: IntegerContainer() < IntegerContainer()
import functools
@ functools.total_ordering class IntegerContainer(object ): def __init__ (self ,
value): self .value = value
def __repr__ (self ):
return "{}({})" .format(self .__class__.__name__, self .value) def __lt__ (self
other):
print ('{!r} - Test less than {!r}' .format(self , other)) return self .value <
other.value
Notice how the > (greater than ) now ends up calling the less than method,
and in some cases even the __eq__ method. This also means that if speed is
of great importance, you should implement each rich comparison method
yourself.
To keep the dictionary structure, you have to iterate over the .items():
min (adict.items())
# Output: ('a', 3)
max (adict.items())
# Output: ('c', 1)
sorted (adict.items())
# Output: [('a', 3), ('b', 5), ('c', 1)]
For sorted , you could create an OrderedDict to keep the sorting while having
a dict -like structure:
By value
Again this is possible using the key argument:
list_of_tuples = [(0 , 10 ), (1 , 15 ), (2 , 8 )]
min (list_of_tuples)
# Output: (0, 10)
but if you want to sort by a specific element in each sequence use the key-
argument:
min (list_of_tuples, key= lambda x: x[0 ]) # Output: (0, 10)
# Sorting by first element
min (list_of_tuples, key= lambda x: x[1 ]) # Output: (2, 8)
# Sorting by second element
sorted (list_of_tuples, key= lambda x: x[0 ]) # Output: [(0, 10), (1, 15), (2,
8)] # Sorting by first element (increasing)
sorted (list_of_tuples, key= lambda x: x[1 ]) # Output: [(2, 8), (0, 10), (1,
15)] # Sorting by first element
min (7 , 2 , 1 , 5 ) # Output: 1
max (7 , 2 , 1 , 5 ) # Output: 7
min ([2 , 7 , 5 ])
# Output: 2
sorted ([2 , 7 , 5 ])[0 ]
# Output: 2
The maximum is a bit more complicated, because sorted keeps order and max
returns the first encountered value. In case there are no duplicates the
maximum is the same as the last element of the sorted return:
max ([2 , 7 , 5 ])
# Output: 7
sorted ([2 , 7 , 5 ])[1 ] # Output: 7
But not if there are multiple elements that are evaluated as having the
maximum value:
class MyClass(object ):
def __init__ (self , value, name): self .value = value
self .name = name
Any iterable containing elements that support < or > operations are allowed.
alist = [1 , 2 , 3 , 4 , 1 , 2 , 1 , 3 , 4 ]
alist.count(1 ) # Out: 3
astring = 'thisisashorttext'
astring.count('t' )
# Out: 4
which would not be possible with collections .Counter which only counts
single characters:
The logic is that the boolean statement produces a array where all
occurrences of the requested values are 1 and all others are zero. So summing
these gives the number of occurencies. This works for arrays of any shape or
dtype.
There are two methods I use to count occurrences of all unique values in
numpy. Unique and bincount. Unique automatically flattens
multidimensional arrays, while bincount only works with 1d arrays only
containing positive integers.
If your data are numpy arrays it is generally much faster to use numpy
methods then to convert your data to generic methods.
foo = 1
bar = 'bar'
baz = 3.14
print (foo)
# out: 1
print (bar)
# out: bar
print (baz)
# out: 3.14
What you should be careful about when using + to print multiple parameters,
though, is that the type of the parameters should be the same. Trying to print
the above example without the cast to string first would result in an error,
because it would try to add the number 1 to the string "bar" and add that to
the number 3.14 .
# Wrong:
# type:int str float print (foo + bar + baz) # will result in an error
print (4 + 5 )
# out: 9
print ("4" + "5" ) # out: 45
print ([4 ] + [5 ]) # out: [4, 5]
Otherwise, using a + can be very helpful for a user to read output of variables
In the example below the output is very easy to read!
The script below demonstrates this
import random
#telling python to include a function to create random numbers randnum =
random .randint(0 , 12 )
If you want to write to a file, you can pass it as the parameter file :
with open ('my_file.txt' , 'w+' ) as my_file: print ("this goes to the file!" , file
my_file) this goes to the file!
>>> print ("<a" , end= '' ); print (" class='jidn'" if 1 else "" , end= '' ); print ("/>"
< a class = 'jidn' />
>>> print ("paragraph1" , end= " \n\n " ); print ("paragraph2" )
paragraph1
paragraph2 >>>
Argument file : send output to someplace other than sys.stdout.
Now you can send your text to either stdout, a file, or StringIO and not care
which you are given. If it quacks like a file, it works like a file.
>>> def sendit(out, *values, sep= ' ' , end= ' \n ' ):
... print (*values, sep= sep, end= end, file = out)
...
>>> sendit(sys .stdout, 'apples' , 'bananas' , 'cherries' , sep= ' \t ' ) apples bananas
cherries
>>> with open ("delete-me.txt" , "w+" ) as f:
... sendit(f, 'apples' , 'bananas' , 'cherries' , sep= ' ' , end= ' \n ' )
...
>>> with open ("delete-me.txt" , "rt" ) as f: ... print (f.read())
...
apples bananas cherries
>>> There is a fourth parameter flush which will forcibly flush the stream.
The first argument of re .match() is the regular expression, the second is the
string to match:
import re
pattern = r"123"
string = "123zzb"
re .match(pattern, string )
# Out: <_sre.SRE_Match object; span=(0, 3), match='123'>
match = re .match(pattern, string )
match.group()
# Out: '123'
You may notice that the pattern variable is a string prefixed with r, which
indicates that the string is a raw string literal .
A raw string literal has a slightly different syntax than a string literal, namely
a backslash \ in a raw string literal means "just a backslash" and there's no
need for doubling up backlashes to escape "escape sequences" such as
newlines (\n), tabs (\t), backspaces (\), form-feeds (\r), and so on. In normal
string literals, each backslash must be doubled up to avoid being taken as the
start of an escape sequence.
Hence, r" \n " is a string of 2 characters: \ and n. Regex patterns also use
backslashes, e.g. \d refers to any digit character. We can avoid having to
double escape our strings (" \\ d" ) by using raw strings (r" \d " ).
For instance:
string = " \\ t123zzb" # here the backslash is escaped, so there's no tab, just '\'
and 't' pattern = " \\ t123" # this will match \t (escaping the backslash) followed
by 123 re .match(pattern, string ).group() # no match
re .match(pattern, " \t 123zzb" ).group() # matches '\t123'
Searching is done anywhere in the string unlike re .match. You can also use
re .findall.
You can also search at the beginning of the string (use ^),
m = re .search("b" , "ABC" )
m is None
# Out: True
For the complete list of all available flags check the docs
Inline flags
From the docs :
(?iLmsux) (One or more letters from the set 'i', 'L', 'm', 's', 'u', 'x'.) The group
matches the empty string; the letters set the corresponding flags: re.I (ignore
case), re.L (locale dependent), re.M (multi-line), re.S (dot matches all), re.U
(Unicode dependent), and re.X (verbose), for the entire regular expression.
This is useful if you wish to include the flags as part of the regular
expression, instead of passing a flag argument to the re.compile() function.
Note that the (?x) flag changes how the expression is parsed. It should be
used first in the expression string, or after one or more whitespace characters.
If there are non-whitespace characters before the flag, the results are
undefined.
print (result.group(0 ))
''' Out:
12
945
444
558
889 '''
import re
data = re .split(r' \s +' , 'James 94 Samantha 417 Scarlett 74' )
print ( data )
# Output: ['James', '94', 'Samantha', '417', 'Scarlett', '74']
match.group(1 )
# Out: 'John Smith'
Creates a capture group that can be referenced by name as well as by index.
Non-capturing groups
Using (?:) creates a group, but the group isn't captured. This means you can
use it as a group, but it won't pollute your "group space".
re .match(r'( \d +)( \+ ( \d +))?' , '11+22' ).groups() # Out: ('11', '+22', '22')
re .match(r'( \d +)(?: \+ ( \d +))?' , '11+22' ).groups() # Out: ('11', '22')
This example matches 11 +22 or 11, but not 11 +. This is since the + sign and
the second term are grouped. On the other hand, the + sign isn't captured.
re .escape('a[b]c' )
# Out: 'a\\[b\\]c'
match = re .search(re .escape('a[b]c' ), 'a[b]c' ) match.group()
# Out: 'a[b]c'
import regex as re
string = "An apple a day keeps the doctor away (I eat an apple everyday)."
rx = re .compile (r'''
This matches "apple" only when it can be found outside of the parentheses.
Here's how it works:
While looking from left to right , the regex engine consumes everything to
the left, the (*SKIP) acts as an "always-true-assertion". Afterwards, it
correctly fails on (*FAIL) and backtracks.
Now it gets to the point of (*SKIP)from right to left (aka while
backtracking) where it is forbidden to go any further to the left. Instead, the
engine is told to throw away anything to the left and jump to the point where
the (*SKIP) was invoked.
import re
text = 'You can try to find an ant in this string'
pattern = 'an? \w ' # find 'an' either with or without a following word character
Match "an" found at: [5,7] Match "an" found at: [20,22] Match "ant" found
at: [23,26]
Chapter 76: Copying data
Section 76.1: Copy a dictionary
A dictionary object has the method copy . It performs a shallow copy of the
dictionary.
>>> d1 = {1 :[]}
>>> d2 = d1.copy ()
>>> d1 is d2
False
>>> d1[1 ] is d2[1 ]
True
>>> l1 = [1 , 2 , 3 ]
>>> l2 = l1[:] # Perform the shallow copy.
>>> l2
[1 , 2 , 3 ]
>>> l1 is l2
False
>>> s1 = {()}
>>> s2 = s1.copy ()
>>> s1 is s2
False
>>> s2.add(3 ) >>> s1
{[]}
>>> s2
{3 , []}
Anything that ends execution of the block causes the context manager's exit
method to be called. This includes exceptions, and can be useful when an
error causes you to prematurely exit from an open file or connection. Exiting
a script without properly closing files/connections is a bad idea, that may
cause data loss or other problems. By using a context manager you can
ensure that precautions are always taken to prevent damage or loss in this
way. This feature was added in Python 2.5.
def __enter__(self ):
print ("Entered" )
# optionally return an object
return "A-instance"
If the context exits with an exception, the information about that exception
will be passed as a triple exc_type, exc_value, traceback (these are the same
variables as returned by the sys .exc_info() function). If the context exits
normally, all three of these arguments will be None . If an exception occurs
and is passed to the __exit__ method, the method can return True in order to
suppress the exception, or the exception will be re-raised at the end of the
__exit__ function.
with AContextManager() as a:
print ("a is %d" % a)
# Entered
# Exited (with an exception)
# Traceback (most recent call last):
# File "<stdin>", line 2, in <module>
# TypeError: %d format: a number is required, not str
Note that in the second example even though an exception occurs in the
middle of the body of the with-statement, the __exit__ handler still gets
executed, before the exception propagates to the outer scope.
If you only need an __exit__ method, you can return the instance of the
context manager:
produces:
Enter
Right in the middle with cm = 3 Exit
@ contextlib.contextmanager
def error_handling_context_manager(num): print ("Enter" )
try :
yield num + 1
except ZeroDivisionError : print ("Caught error" )
finally :
print ("Cleaning up" )
print ("Exit" )
This produces:
Enter
Dividing by cm = 0 Caught error
Cleaning up
Exit
class File():
def __init__ (self , filename, mode):
self .filename = filename
self .mode = mode
def __enter__(self ):
self .open_file = open (self .filename, self .mode) return self .open_file
The special variable __name__ is not set by the user. It is mostly used to
check whether or not the module is being run by itself or run because an
import was performed. To avoid your module to run certain parts of its code
when it gets imported, check if __name__ == '__main__' .
def f(x):
x += 2 return x
print (f)
# <function f at 0x029976B0> print (f.__name__)
#f
print (C)
# <class '__main__.C'> print (C.__name__)
#C
print (os )
# <module 'os' from '/spam/eggs/'> print (os .__name__)
# os
The __name__ attribute is not, however, the name of the variable which
references the class, method or function, rather it is the name given to it when
defined.
def f(): pass
print (f.__name__) # f - as expected
g=f
print (g.__name__)
# f - even though the variable is named g, the function is still named f
def enter_exit_info(func):
def wrapper(*arg, **kw):
print '-- entering' , func.__name__ res = func(*arg, **kw)
print '-- exiting' , func.__name__ return res
return wrapper
@ enter_exit_info
def f(x):
print 'In:' , x
res = x + 2
print 'Out:' , res
return res
a = f(2 )
# Outputs:
# -- entering f # In: 2
# Out: 4
# -- exiting f
+-- package_name
||
| +-- __init__ .py
|
+-- setup.py
The __init__ .py contains only the line def foo(): return 100 .
The following setup.py will define the package:
from setuptools import setup
setup(
name= 'package_name' ,
version= '0.1' ,
description= 'Package Description' , url= 'http://example.com' ,
install_requires= [],
packages= ['package_name' ],
# package name
# version
# short description
# package URL
# list of packages this package depends # on.
# List of module names that installing # this package will provide.
)
virtualenv is great to test package installs without modifying your other
Python environments:
$ virtualenv .virtualenv
...
$ source .virtualenv/bin/activate $ python setup.py install
running install
...
Installed .../package_name0.1 -....egg ...
$ python
>>> import package_name
>>> package_name.foo()
100
[ distutils ]
index-servers = pypi
pypitest
[pypi]
repository= https://pypi.python.org/pypi username= your_username
password= your_password
[pypitest]
repository= https://testpypi.python.org/pypi username= your_username
password= your_password
It is safer to use twine for uploading packages, so make sure that is installed.
$ pip install twine Register and Upload to testpypi (optional)
# Using virtualenv
$ mkdir testenv
$ cd testenv
$ virtualenv .virtualenv
...
$ source .virtualenv/ bin/ activate
# Test from testpypi
( .virtualenv) pip install --verbose --extra-index-url https://
testpypi.python.org/ pypi package_name
...
# Or test from PyPI
( .virtualenv) $ pip install package_name
...
( .virtualenv) $ python
Python 3.5.1 ( default, Jan 27 2016, 19:16:39)
[ GCC 4.2.1 Compatible Apple LLVM 7.0.2 ( clang-700.1.81)] on darwin
Type "help" , "copyright" , "credits" or "license" for more information. >>>
import package_name
>>> package_name.foo() 100
import pip
command = 'install'
parameter = 'selenium'
second_param = 'numpy' # You can give as many package names as needed
switch = '--upgrade'
list .append(i.key)
pip.main(['install' ]+list +['--upgrade' ])
If you don't want to stop when some installs fail, call installation in loop.
for i in installed:
pip.main(['install' ]+i.key+['--upgrade' ])
When you use python file as module there is no need always check if
package is installed but it is still useful for scripts.
if __name__ == '__main__' : try :
import requests
except ImportError :
print ("To use this module you need 'requests' module" ) t = input ('Install
requests? y/n: ' )
if t == 'y' :
import pip
pip.main(['install' , 'requests' ])
import requests
import os
import sys
pass
else :
import os
import sys
print ('Some functionality can be unavailable.' )
else :
import requests
import os
import sys
Many packages for example on version 3.4 would run on 3.6 just fine, but if
there are no distributions for specific platform, they can't be installed, but
there is workaround. In .whl files (known as wheels) naming convention
decide whether you can install package on specified platform. Eg.
scikit_learn‑0.18.1‑cp36‑cp36m‑win_amd64.whl[package_name]-[version]-
[python interpreter]-[pythoninterpreter]-[Operating System].whl. If name of
wheel file is changed, so platform does match, pip tries to install package
even if platform or python version does not match. Removing platform or
interpreter from name will rise an error in newest version of pip module
kjhfkjdf.whl is not a valid wheel filename..
$ pip list
# example output
docutils (0.9.1)
Jinja2 (2.6 )
Pygments (1.5 )
Sphinx (1.1.2)
To uninstall a package:
$ pip uninstall SomePackage
This command takes all packages in the local virtualenv and checks if they
are outdated. From that list, it gets the package name and then pipes that to a
pip install -U command. At the end of this process, all local packages should
be updated.
This command takes all packages in the local virtualenv and checks if they
are outdated. From that list, it gets the package name and then pipes that to a
pip install -U command. At the end of this process, all local packages should
be updated.
Section 82.7: Create a requirements.txt file of all packages on
the system
If you have both Python 3 and Python 2 installed, you can specify which
version of Python you would like pip to use. This is useful when packages
only support Python 2 or 3 or when you wish to test with both.
If you want to install packages for Python 2, run either:
pip install [package]
or:
pip2 install [package]
If you would like to install packages for Python 3, do:
pip3 install [package]
You can also invoke installation of a package to a specific python installation
with:
\path\to\that\python.exe -m pip install some_package # on Windows OR
/usr/bin/python25 -m pip install some_package # on OS-X/Linux
On Windows, if you have both python 2 and python 3 installed, and on your
path and your python 3 is greater than 3.4 then you will probably also have
the python launcher py on your system path. You can then do tricks like:
The problem is that the package that you are trying to install contains a C or
C++ extension and is not currently available as a pre-built wheel from the
python package index, pypi , and on windows you do not have the tool chain
needed to build such items.
The simplest answer is to go to Christoph Gohlke's excellent site and locate
the appropriate version of the libraries that you need. By appropriate in the
package name a -cp NN - has to match your version of python, i.e. if you are
using windows 32 bit python even on win64 the name must include the name
must include and if using the 64 bit python it must include include and then
the python version must match, i.e. for Python 34 the filename must include -
cp -cp , etc. this is basically the magic that pip does for you on the pypi
site.
Python 2.7 used Visual Studio 2008, Python 3.3 and 3.4 used Visual
Studio 2010, and Python 3.5+ uses Visual Studio 2015.
Then you may need to locate the header files, at the matching revision for
any libraries that your desired package links to and download those to
an appropriate locations.
Finally you can let pip do your build - of course if the package has
dependencies that you don't yet have you may also need to find the
header files for them as well.
You can also use pip to install development versions of packages from
github and other locations, since such code is in flux it is very unlikely to
have wheels built for it, so any impure packages will require the presence
of the build tools, and they may be broken at any time so the user is
strongly encouraged to only install such packages in a virtual
environment.
2. Let pip handle the download & install for you with: pip
installURL/of/package/repository - you may also need to use the --trusted-
host, --client-cert and/or --proxy flags for this to work correctly,
especially in a corporate environment. e.g:
)
args = parser .parse_args()
)
$ python hello.py - help
usage: hello.py [-h] [-g GREETING] name
positional arguments:
name name of user
optional arguments:
-h, -help show this help message and exit
-g GREETING, --greeting GREETING
Whenever a Python script is invoked from the command line, the user
may supply additional command line arguments which will be passed on
to the script. These arguments will be available to the programmer from
the system variable sys .argv ("argv" is a traditional name used in most
programming languages, and it means "argument vector").
By convention, the first element in the sys .argv list is the name of the
Python script itself, while the rest of the elements are the tokens passed
by the user when invoking the script.
# cli.py
import sys
print (sys .argv)
Here's another example of how to use argv. We first strip off the initial
element of sys.argv because it contains the script's name. Then we
combine the rest of the arguments into a single sentence, and finally
print that sentence prepending the name of the currently logged-in user
(so that it emulates a chat program).
import argparse
parser = argparse.ArgumentParser()
group = parser .add_mutually_exclusive_group() group.add_argument("-
f" , "--foo" ) group.add_argument("-b" , "--bar" ) args = parser
.parse_args()
print "foo = " , args.foo
print "bar = " , args.bar
If you try to run the script specifying both --foo and --bar arguments, the
script will complain with the below message.
error: argument -b/--bar: not allowed with argument -f/--foo
Options:
-a Print all the things.
-b Get more bees into the path.
"""
from docopt import docopt
if __name__ == "__main__" :
args = docopt(__doc__)
import pprint ; pprint .pprint (args)
Sample runs:
$ python script_name.py
Usage:
script_name.py [-a] [-b] < path>
$ python script_name.py something
{'-a' : False ,
'-b' : False ,
'<path>' : 'something' }
$ python script_name.py something -a
{'-a' : True ,
'-b' : False ,
'<path>' : 'something' }
$ python script_name.py -b something -a
{'-a' : True ,
'-b' : True ,
'<path>' : 'something' }
You can create parser error messages according to your script needs.
This is through the argparse.ArgumentParser.error function. The below
example shows the script printing a usage and an error message to stderr
when --foo is given but not --bar.
parser .error( "--foo requires --bar. You did not specify bar." )
print "foo =" , args.foo print "bar =" , args.bar
Assuming your script name is sample.py, and we run: python sample.py
--foo ds_in_fridge
The script will complain with the following:
usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.
import argparse
Simple example
positional arguments:
name Who to greet
optional arguments:
-h, -help
--bar_this BAR_THIS
--bar_that BAR_THAT
--foo_this FOO_THIS
--foo_that FOO_THAT show this help message and exit
There are some situations where you want to separate your arguments
into further conceptual sections to assist your user. For example, you
may wish to have all the input options in one group, and all the output
formatting options in another. The above example can be adjusted to
separate the --foo_* args from the --bar_* args like so.
import argparse
parser = argparse.ArgumentParser(description = 'Simple example' )
Foo options:
--bar_this BAR_THIS
--bar_that BAR_THAT
Bar options:
--foo_this FOO_THIS
--foo_that FOO_THAT
"""
from docopt_dispatch import dispatch
@ dispatch.on('--development' )
def development(host, port, **kwargs): print ('in *development* mode' )
@ dispatch.on('--production' )
In both the above snippets, the process.poll() is None until the subprocess
finishes. This is used to exit the loop once there is no more output to
read.
The same procedure could be applied to the stderr of the subprocess.
The simplest use case is using the subprocess .call function. It accepts a
list as the first argument. The first item in the list should be the external
application you want to call. The other items in the list are arguments
that will be passed to that application.
The rules to create the list are not always straightforward to follow,
especially with complex commands. Fortunately, there is a very helpful
tool that allows doing that: shlex . The easiest way of creating the list to
be used as command is the following:
import shlex
cmd_to_subprocess = shlex .split(command_used_in_the_shell)
A simple example:
import shlex
shlex .split( 'ls --color -l -t -r' ) out: [ 'ls' , '--color' , '-l' , '-t' , '-r' ]
packages
List of Python packages (that is, directories containing modules) to
include. This can be specified manually, but a call to
setuptools.find_packages() is typically used instead. py_modulesList of
top-level Python modules (that is, single .py files) to include.
setup(name = 'foo' ,
version= '1.0' ,
py_modules= ['foo' ],
)
To create a source distribution for this module, you would create a setup
script, setup.py, containing the above code, and run this command from
a terminal:
python setup.py sdist
sdist will create an archive file (e.g., tarball on Unix, ZIP file on
Windows) containing your setup script setup.py, and your module
foo.py. The archive file will be named foo-1.0.tar.gz (or .zip), and will
unpack into a directory foo-1.0.
If an end-user wishes to install your foo module, all she has to do is
download foo-1.0.tar.gz (or .zip), unpack it, and—from the foo-1.0
directory—run
python setup.py install
Section 85.2: Using source control metadata in setup.py
setup(
setup_requires= ['setuptools_scm' ], use_scm_version= True ,
packages= find_packages(),
include_package_data= True ,
)
This example uses both features; to only use SCM metadata for the
version, replace the call to find_packages() with your manual package
list, or to only use the package finder, remove use_scm_version = True .
Command line scripts inside python packages are common. You can
organise your package in such a way that when a user installs the
package, the script will be available on their path.
If you had the greetings package which had the command line script
hello_world.py.
greetings/
greetings/
__init__ .py
hello_world.py
def run(self ):
import sphinx
sphinx.build_main(['setup.py' , '-b' , 'html' , './doc' , './doc/_build/html' ])
sphinx.build_main(['setup.py' , '-b' , 'man' , './doc' , './doc/_build/man' ])
setup(
...
cmdclass= cmdclasses, )
At this next step is where things might get a little confusing. Looking at
our new expression, we already know what n is. However, we don't yet
know what factorial(n - 1 ) is. First, n - 1 evaluates to 2. Then, 2 is passed
to factorial as the value for n. Since this is a new function call, a second
environment is created to store this new n. Let A be the first
environment and B be the second environment. A still exists and equals
{'n' : 3 }, however, B (which equals {'n' : 2 }) is the current environment.
Looking at the function body, the return value is, again, n * factorial(n -
1 ). Without evaluating this expression, let's substitute it into the original
return expression. By doing this, we're mentally discarding B , so
remember to substitute n accordingly (i.e. references to B 's n are
replaced with n - 1 which uses A 's n). Now, the original return
expression becomes n * ((n - 1 ) * factorial((n
- 1 ) - 1 )). Take a second to ensure that you understand why this is so.
def factorial(n):
if n == 0 :
return 1
elif n == 1 :
return 1
else :
return n * factorial(n - 1 )
You may also have multiple recursion cases, but we won't get into that
since it's relatively uncommon and is often difficult to mentally process.
You can also have “parallel” recursive function calls. For example,
consider the Fibonacci sequence which is defined as follows:
( fib((n - 2 ) - 2 ) +
(
fib(((n - 2 ) - 1 ) - 2 ) +
fib(((n - 2 ) - 1 ) - 1 )
)
)
+
(
( fib(((n - 1 ) - 2 ) - 2 ) +
fib(((n - 1 ) - 2 ) - 1 )
)
+
(
fib(((n - 1 ) - 1 ) - 2 ) +
(
fib((((n - 1 ) - 1 ) - 1 ) - 2 ) +
fib((((n - 1 ) - 1 ) - 1 ) - 1 )
)
)
)
This becomes ( 1 + ( 0 + 1 )) + (( 0 + 1 ) + ( 1 + ( 0 + 1 ))) which of course evaluates
to 5.
Now, let's cover a few more vocabulary terms:
A tail call is simply a recursive function call which is the last operation to
be performed before returning a value. To be clear, return foo(n - 1 ) is a
tail call, but return foo(n - 1 ) + 1 is not (since the addition is the last
operation).
Tail call optimization (TCO) is a way to automatically reduce recursion
in recursive functions. Tail call elimination (TCE) is the reduction of a
tail call to an expression that can be evaluated without recursion. TCE is
a type of TCO.
product * = n n = 1
return product
def fib(n):
a, b = 0 , 1
while n > 0 :
a,b=b,a+bn=1
return a
This is usually the most efficient way to manually eliminate recursion,
but it can become rather difficult for more complex functions.
Another useful tool is Python's lru_cache decorator which can be used to
reduce the number of redundant calculations.
You now have an idea as to how to avoid recursion in Python, but when
should you use recursion? The answer is “not often”. All recursive
functions can be implemented iteratively. It's simply a matter of figuring
out how to do so. However, there are rare cases in which recursion is
okay. Recursion is common in Python when the expected inputs wouldn't
cause a significant number of a recursive function calls.
Please note that the above example for the Fibonacci sequence, although
good at showing how to apply the definition in python and later use of
the lru cache, has an inefficient running time since it makes 2 recursive
calls for each non base case. The number of calls to the function grows
exponentially to n.
Rather non-intuitively a more efficient implementation would use linear
recursion:
def fib(n):
if n <= 1 :
return (n, 0 )
else :
(a, b) = fib(n - 1 )
return (a + b, a)
But that one has the issue of returning a pair of numbers. This emphasizes
that some functions really do not gain much from recursion.
root
-A
- AA
- AB
-B
- BA
- BB
- BBA
Now, if we wish to list all the names of the elements, we could do this
with a simple for-loop. We assume there is a function get_name() to
return a string of the name of a node, a function get_children() to return
a list of all the sub-nodes of a given node in the tree, and a function
get_root() to get the root node.
root = get_root(tree)
for node in get_children(root):
print (get_name(node))
for child in get_children(node):
print (get_name(child))
for grand_child in get_children(child): print (get_name(grand_child)) #
prints: A, AA, AB, B, BA, BB, BBA
This works well and fast, but what if the sub-nodes, got sub-nodes of its
own? And those sub-nodes might have more sub-nodes... What if you
don't know beforehand how many there will be? A method to solve this
is the use of recursion.
def list_tree_names(node):
for child in get_children(node): print (get_name(child))
list_tree_names(node= child)
return lst
list_tree_names(node = get_root(tree))
# returns ['A', 'AA', 'AB', 'B', 'BA', 'BB', 'BBA']
else :
print n
countdown(n1 )
Any computation that can be made using iteration can also be made
using recursion. Here is a version of find_max written using tail
recursion:
def find_max(seq , max_so_far):
if not seq:
return max_so_far
By default Python's recursion stack cannot exceed 1000 frames. This can
be changed by setting the sys .setrecursionlimit(15000 ) which is faster
however, this method consumes more memory. Instead, we can also solve
the Tail Recursion problem using stack introspection.
#!/usr/bin/env python2.4
# This program shows off a python decorator which implements tail call
optimization. It # does this by throwing an exception if it is its own
grandparent, and catching such # exceptions to recall the stack.
import sys
class TailRecurseException:
def __init__ (self , args, kwargs): self .args = args
self .kwargs = kwargs
def tail_call_optimized(g):
"""
This function decorates a function with tail call optimization. It does this
by throwing an exception if it is its own grandparent, and catching such
exceptions to fake the tail call optimization.
@ tail_call_optimized
def factorial(n, acc= 1 ):
"calculate a factorial"
if n == 0 :
return acc
return factorial(n1 , n*acc)
print factorial(10000 )
# prints a big, big number,
# but doesn't hit the recursion limit.
Fibonacci Example:
@ tail_call_optimized
def fib(i , current = 0 , next = 1 ):
if i == 0 :
return current
else :
return fib(i - 1 , next, current + next)
print fib(10000 )
# also prints a big number,
# but doesn't hit the recursion limit.
Apart from specifying the type of the arguments, one could also indicate
the return value of a function call. This is done by adding the ->
character followed by the type after the closing parenthesis in the
argument list but before the : at the end of the function declaration:
The typing. TypeVar is a generic type factory. It's primary goal is to serve
as a parameter/placeholder for generic function/class/method
annotations:
import typing
T = typing.TypeVar( "T" )
x = 3 # type: int
x = negate(x)
x = 'a type-checker might catch this error'
class Foo:
x: int
y: str = 'abc'
print (typing.get_type_hints(Foo))
# ChainMap({'x': <class 'int'>, 'y': <class 'str'>}, {})
Alternatively, they can be accessed by using the __annotations__ special
variable or attribute:
x: int
print (__annotations__)
# {'x': <class 'int'>}
class C:
s: str
print (C.__annotations__)
# {'s': <class 'str'>}
class A:
x = None # type: float
def __init__ (self , x: float ) > None :
"""
self should not be annotated
init should be annotated to return None
"""
self .x = x
@ classmethod
def from_int(cls, x: int ) > 'A' :
"""
cls should not be annotated
Use forward reference to refer to current class with string literal 'A'
"""
return cls(float (x))
Use try ... except : to catch exceptions. You should specify as precise an
exception as you can:
try :
x=5/0
except ZeroDivisionError as e:
# `e` is the exception object
print ("Got a divide by zero! The exception was:" , e)
# handle exceptional case
x=0
finally :
print "The END"
# it runs no matter what execute.
try : 5 / 0
except ArithmeticError :
print ("Got arithmetic error" )
try :
very_difficult_function()
except Exception :
# log / try to reconnect / exit gratiously
finally :
print "The END"
# it runs no matter what execute.
try : even_more_difficult_function()
except :
pass # do whatever needed
In most cases it's bad practice. It might catch more than intended, such
as SystemExit , KeyboardInterrupt and MemoryError - each of which
should generally be handled differently than usual system or logic errors.
It also means there's no clear understanding for what the internal code
may do wrong and how to recover properly from that condition. If
you're catching every error, you won't know what error occurred or how
to fix it.
Sometimes you want to catch an exception just to inspect it, e.g. for
logging purposes. After the inspection, you want the exception to
continue propagating as it did before.
In this case, simply use the raise statement with no parameters.
try :
5/0
except ZeroDivisionError :
print ("Got an error" )
raise
Keep in mind, though, that someone further up in the caller stack can
still catch the exception and handle it somehow. The done output could
be a nuisance in this case because it will happen in any case (caught or
not caught). So it might be a better idea to raise a different exception,
containing your comment about the situation as well as the original
exception:
try : 5 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError ("Got an error" , e)
But this has the drawback of reducing the exception trace to exactly this
raise while the raise without argument retains the original exception trace.
In Python 3 you can keep the original stack by using the raise - from
syntax: raise ZeroDivisionError ( "Got an error" ) from e
Section 88.4: Catching multiple exceptions
try :
d = {}
a = d[1 ]
b = d.non_existing_field
try : d = {}
a = d[1 ]
b = d.non_existing_field
except KeyError as e:
print ("A KeyError has occurred. Exception message:" , e)
except AttributeError as e:
print ("An AttributeError has occurred. Exception message:" , e)
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +-- ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError | +-- UnicodeEncodeError | +--
UnicodeTranslateError +-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning +-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError | | +-- ConnectionRefusedError | | +--
ConnectionResetError | +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError | +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError | +-- UnicodeEncodeError | +--
UnicodeTranslateError +-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning +-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Section 88.6: Else
Code in an else block will only be run if no exceptions were raised by the
code in the try block. This is useful if you have some code you don’t want
to run if an exception is thrown, but you don’t want exceptions thrown
by that code to be caught.
For example:
try :
data = {1 : 'one' , 2 : 'two' } print (data[1 ])
except KeyError as e:
print ('key not found' )
else :
raise ValueError ()
# Output: one
# Output: ValueError
Note that this kind of else : cannot be combined with an if starting the
else-clause to an elif . If you have a following if it needs to stay indented
below that else ::
try : ...
except ...: ...
else :
if ...: ... elif ...: ... else :
...
class FooException(Exception ):
pass
try :
raise FooException("insert description here" )
except FooException:
print ("A FooException was raised." )
def foo(x):
# function that only accepts positive values of x if x < 0 :
User input
Imagine you want a user to enter a number via input . You want to ensure
that the input is a number. You can use try / except for this:
Python 3.x Version ≥ 3.0 while True :
try :
nb = int ( input ( 'Enter a number: ' )) break
except ValueError :
print ( 'This is not a number, try again.' )
Note: Python 2.x would use raw_input instead; the function input exists in
Python 2.x but has different semantics. In the above example, input would
also accept expressions such as 2 + 2 which evaluate to a number.
If the input could not be converted to an integer, a ValueError is raised.
You can catch it with except . If no exception is raised, break jumps out of
the loop. After the loop, nb contains an integer.
Dictionaries
Imagine you are iterating over a list of consecutive integers, like range (n),
and you have a list of dictionaries d that contains information about
things to do when you encounter some particular integers, say skip the
d[i] next ones .
d = [{ 7 : 3 } , { 25 : 9 } , { 38 : 5 }]
dic = d[i]
i += dic[i]
except KeyError :
i+=1
A KeyError will be raised when you try to get a value from a dictionary
for a key that doesn’t exist.
Exceptions are just regular Python objects that inherit from the built-in
BaseException. A Python script can use the raise statement to interrupt
execution, causing Python to print a stack trace of the call stack at that
point and a representation of the exception instance. For example:
File "<stdin>" , line 1 , in < module > File "<stdin>" , line 2 , in failing_function
ValueError : Example error !
which says that a ValueError with the message 'Example error!' was raised
by our failing_function(), which was executed in the interpreter.
Calling code can choose to handle any and all types of exception that a
call can raise:
>>> try :
... failing_function()
... except ValueError :
... print ('Handled the error' ) Handled the error
You can get hold of the exception objects by assigning them in the except
... part of the exception handling code:
>>> try :
... failing_function()
... except ValueError as e:
... print ('Caught exception' , repr (e)) Caught exception ValueError
('Example error!' , )
except SomeException as e:
log_error(e)
raise # re-raise the error
finally :
free_expensive_resource( resource ) This pattern is often better handled
with context managers (using the with statement).
>>> try :
5/0
except ZeroDivisionError as e:
raise ValueError ("Division failed" ) from e
Traceback (most recent call last): File "<stdin>" , line 2 , in < module>
ZeroDivisionError : division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "<stdin>" , line 4 , in < module>
ValueError : Division failed
try :
raise CustomError('Can you catch me ?' )
except CustomError as e:
print ('Catched CustomError :{}' .format(e))
except Exception as e:
print ('Generic exception: {}' .format(e))
AssertError
The assert statement exists in almost every programming language. When
you do:
assert condition
or:
assert condition , message
It's equivalent to this:
if __debug__:
if not condition: raise AssertionError (message)
Assertions can include an optional message, and you can disable them
when you're done debugging.
KeyboardInterrupt
Error raised when the user presses the interrupt key, normally Ctrl + C
or del .
ZeroDivisionError
You tried to calculate 1 / 0 which is undefined. See this example to find the
divisors of a number:
Python 2.x Version ≥ 2.0 Version ≤ 2.7
div = float ( raw_input ( "Divisors of: " ))
for x in xrange (div+ 1 ): #includes the number itself and zero
if div/x == div//x:
print x , "is a divisor of" , div
Python 3.x Version ≥ 3.0
div = int ( input ( "Divisors of: " ))
for x in range (div+ 1 ): #includes the number itself and zero
if div/x == div//x:
print (x , "is a divisor of" , div)
It raises ZeroDivisionError because the for loop assigns that value to x.
Instead it should be:
Python 2.x Version ≥ 2.0 Version ≤ 2.7
div = float ( raw_input ( "Divisors of: " ))
for x in xrange ( 1 , div+ 1 ): #includes the number itself but not zero if div/x
div//x:
print x , "is a divisor of" , div Python 3.x Version ≥ 3.0
div = int ( input ( "Divisors of: " ))
for x in range ( 1 , div+ 1 ): #includes the number itself but not zero if div/x
div//x:
print (x , "is a divisor of" , div)
Is raised when you tried to use a variable, method or function that is not
initialized (at least not before). In other words, it is raised when a
requested local or global name is not found. It's possible that you
misspelt the name of the object or forgot to import something. Also
maybe it's in another scope. We'll cover those with separate examples.
def sqrt():
x = float (input ("Value: " )) return math .sqrt(x)
As an example:
for i in range (4 ): d = i * 2
print (d)
d is accessible because the for loop does not mark a new scope, but if it
did, we would have an error and its behavior would be similar to:
def noaccess():
for i in range ( 4 ): d = i * 2
noaccess()
print (d)
Python says NameError : name 'd' is not defined
Example
Here we are saying that bar is the zeroth item of 1. Nonsense:
foo = 1
bar = foo[ 0 ]
This is a more discrete version: In this example for tries to set x to
amount[ 0 ], the first item in an iterable but it can't because amount is an
int:
amount = 10
for x in amount: print (x)
TypeError: '???' object is not callable
You are defining a variable and calling it later (like what you do with a
function or method)
Example
foo = "notAFunction" foo()
Returns
>>> print "hello world" File "<stdin>" , line 1 print "hello world" ^
SyntaxError : invalid syntax
Because the print statement was replaced with the print () function , so you
want: print ( "hello world" ) # Note this is valid for both Py2 & Py3
Note : Use the keyword pass (that makes absolutely nothing) to just put
an if, else , except , class , method or definition but not say what will
happen if called/condition is true (but do it later, or in the case of except
: just do nothing):
print (response.code )
# Prints: 200
print (response.read())
# Prints: b'<!DOCTYPE
html>\r\n<html>\r\n<head>\r\n\r\n<title>Documentation - Stack
Overflow</title>
The module has been updated for Python 3.x, but use cases remain
basically the same. urllib .request.urlopen will return a similar file-like
object.
import urllib2
response = urllib2 .urlopen("http://stackoverflow.com/" )
data = response.read()
encoding = response.info().getencoding()
html = data.decode(encoding)
First you have to set up a new Scrapy project. Enter a directory where
you’d like to store your code and run:
scrapy startproject projectName
To scrape we need a spider. Spiders define how a certain site will be
scraped. Here’s the code for a spider that follows the links to the top
voted questions on StackOverflow and scrapes some data from each page
( source ):
import scrapy
class StackOverflowSpider(scrapy.Spider):
name = 'stackoverflow' # each spider has a unique name
start_urls = ['http://stackoverflow.com/questions?sort=votes' ] # the
parsing starts from a
}
Save your spider classes in the projectName\spiders directory. In this
case projectName\spiders\stackoverflow_spider.py.
Now you can use your spider. For example, try running (in the project's
directory): scrapy crawl stackoverflow
def main():
r = requests.get("https://httpbin.org" )
html_source = r.text
root_element = lxml.html.fromstring(html_source) # Note
root_element.xpath() gives a *list* of results. # XPath specifies a path to
the element we want.
page_title = root_element.xpath('/html/head/title/text()' )[0 ] print
(page_title)
# get cookies
response = session.get('http://httpbin.org/cookies' )
print (response.text)
# with class "dataTable" # We extract the first tag from the list, since that's
what we desire
datatable = datatable_tags[0 ]
# Now since we want problem names, they are contained in <b> tags, which
are # directly nested under <a> tags
prob_tags = datatable.select ('a > b' )
prob_names = [tag.getText().strip() for tag in prob_tags]
print prob_names
The standard library module urllib .request can be used to download web
content:
from urllib .request import urlopen
response = urlopen( 'http://stackoverflow.com/questions?sort=votes' )
data = response.read()
BeautifulSoup has a limited support for CSS selectors , but covers most
commonly used ones. Use SELECT () method to find multiple elements
and select_one () to find a single element.
Basic example:
from bs4 import BeautifulSoup
data = """
<ul>
<li class="item">item1</li> <li class="item">item2</li> <li
class="item">item3</li>
</ul>
"""
item1
item2
item3
html = """
<h1>Sales</h1>
<table id="table">
<tr>
doc = PyQuery(html)
title = doc( 'h1' ).text()
print title
table_data = []
<div>
<label>Name:</label>
John Smith
</div>
And you need to locate the text "John Smith" after the label element.
In this case, you can locate the label element by text and then use .
next_sibling property :
from bs4 import BeautifulSoup
data = """
<div>
<label>Name:</label> John Smith
</div>
"""
Import the ElementTree object, open the relevant .xml file and get the
root tag:
There are a few ways to search through the tree. First is by iteration:
for child in root:
print (child.tag , child.attrib)
Otherwise you can reference specific locations like a list:
print (root[ 0 ][ 1 ].text)
To search for specific tags by name, use the .find or .findall:
print (root.findall( "myTag" ))
print (root[ 0 ].find( "myOtherTag" ))
ET.dump(p)
# Output will be like this
#<parent><child1 /></parent>
Starting with version 2.7 ElementTree has a better support for XPath
queries. XPath is a syntax to enable you to navigate through an xml like
SQL is used to search through a database. Both find and findall
functions support XPath. The xml below will be used for this example
<Catalog>
<Books>
</Book>
<Book id = "5" price = "5.95" >
<Title>The Colour of Magic</Title>
<Author>Terry Pratchett</Author>
</Book>
<Book id = "7" price = "6.95" >
<Title>The Eye of The World</Title>
<Author>Robert Jordan</Author>
</Book>
</Books>
</Catalog>
Sometimes we don't want to load the entire XML file in order to get the
information we need. In these instances, being able to incrementally load
the relevant sections and then delete them when we are finished is useful.
With the iterparse function you can edit the element tree that is stored
while parsing the XML.
multiple_files = [
('images' , ('foo.png' , open ('foo.png' , 'rb' ), 'image/png' )), ('images' ,
('bar.png' , open ('bar.png' , 'rb' ), 'image/png' ))]
foo = post( 'http://httpbin.org/post' , files = multiple_files)
class CustomAuth(AuthBase):
return r
This can then be utilized with the following code:
foo = get( 'http://test.com/admin' , auth = CustomAuth( 'SecretHeader' ,
'CustomUserAgent' , 'user' , 'password' ))
proxies = {
'http' : 'http://192.168.0.128:3128' ,
'https' : 'http://192.168.0.127:1080' ,
}
foo = requests.post( 'http://httpbin.org/post' , proxies = proxies)
HTTP Basic Authentication can be provided in this manner:
proxies = { 'http' : 'http://user:pass@192.168.0.128:312' } foo = requests.post(
'http://httpbin.org/post' , proxies = proxies)
SOCKS Proxies
The use of socks proxies requires 3rd party dependencies
requests[socks], once installed socks proxies are used in a very similar
way to HTTPBasicAuth:
proxies = {
'http' : 'socks5://user:pass@host:port' , 'https' :
'socks5://user:pass@host:port' }
APP = ['test.py' ]
DATA_FILES = []
OPTIONS = {'argv_emulation' : True }
setup(
app= APP,
data_files= DATA_FILES,
options= {'py2app' : OPTIONS},
setup_requires= ['py2app' ],
)
To add an icon file (this file must have a .icns extension), or include
images in your application as reference, change your options as shown:
DATA_FILES = [ 'myInsertedImage.jpg' ]
OPTIONS = { 'argv_emulation' : True , 'iconfile' : 'myCoolIcon.icns' }
Finally enter this into terminal:
python setup.py py2app
The script should run and you will find your finished application in the
dist folder.
Use the following options for more customization:
optimize (-O) optimization level: -O1 for "python -O" , -O2 for "python -
OO" , and -O0 to disable [default: -O0] includes (-i) comma-separated list
of modules to include packages (-p) comma-separated list of packages to
include
extension Bundle extension [default:.app for app , .plugin for plugin]
extra-scripts comma-separated list of additional scripts to include in an
application or plugin.
setup(
name = application_title,
version = "0.1" ,
description = "Your Description" ,
options = {"build_exe" : {"includes" : includes }}, executables =
[Executable(main_python_file, base = base)])
class Cash(object ):
def __init__ (self , value):
self .value = value
@ property
def formatted( self ):
return '${:.2f}' .format( self .value)
@ formatted.setter
def formatted( self , new ):
self .value = float ( new [ 1 :])
To use this:
When you inherit from a class with a property, you can provide a new
implementation for one or more of the property getter, setter or deleter
functions, by referencing the property object on the parent class :
class BaseClass(object ):
@ property
def foo(self ):
return some_calculated_value()
@ foo.setter
def foo( self , value):
do_something_with_value(value)
class DerivedClass(BaseClass):
@ BaseClass.foo.setter
def foo(self , value):
class A:
p = 1234
def getX (self ):
A.q = 5678
class B:
def getZ ( self ): return self .z_ def setZ ( self , value): self .z_ = value
z = property (getZ , setZ)
class C:
def __init__ ( self ): self .offset = 1234 def getW ( self ):
return self .w_ + self .offset
def setW ( self , value):
self .w_ = value - self .offset
w = property (getW , setW)
a1 = A () a2 = A ()
a1.y2 = 1000 a2.y2 = 2000
a1.x = 5 a1.y = 6
a2.x = 7 a2.y = 8
a1.t = 77 a1.u = 88
print (a1.x, a1.y, a1.y2) print (a2.x, a2.y, a2.y2) print (a1.p, a2.p, a1.q,
a2.q)
b.z = 100100
c.z = 200200
c.w = 300300
c.w = 400400
c.z = 500500
b.z = 600600
Below are the operators that can be overloaded in classes, along with the
method definitions that are required, and an example of the operator in
use within an expression.
N.B. The use of other as a variable name is not mandatory, but is
considered the norm.
Operator
+ Addition
- Subtraction
* Multiplication
@ Matrix Multiplication / Division
/ Division
// Floor Division
% Modulo/Remainder ** Power
<< Bitwise Left Shift >> Bitwise Right Shift & Bitwise AND
^ Bitwise XOR
| (Bitwise OR)
- Negation (Arithmetic) + Positive
~ Bitwise NOT
< Less than
<= Less than or Equal to == Equal to
!= Not Equal to
> Greater than
Method
__add__ ( self , other)
Expression
a1 + a2
a1 - a2
a1 * a2
a1 @ a2 (Python 3.5 ) a1 / a2 (Python 2 only ) a1 / a2 (Python 3 ) a1 // a2
a1 % a2
__pow__ (self , other[, modulo]) a1 ** a2 __lshift__ (self , other) a1 << a2
__rshift__ (self , other) a1 >> a2 __and__ (self , other) a1 & a2
__xor__ (self , other) a1 ^ a2
__or__ (self , other) a1 | a2
__neg__ (self ) -a1 __pos__ (self ) +a1 __invert__ (self ) ~ a1 __lt__ (self ,
other) a1 < a2
__le__ (self , other) a1 <= a2 __eq__ (self , other) a1 == a2 __ne__ (self ,
other) a1 != a2 __gt__ (self , other) a1 > a2
>= Greater than or Equal to__ge__ (self , other) a1 >= a2 [index] Index
operator __getitem__ (self , index) a1[index] in In operator __contains__
(self , other) a2 in a1 (*args, ...) Calling __call__ (self , *args, **kwargs)
a1(*args, **kwargs)
The optional parameter modulo for __pow__ is only used by the pow built-in
function.
Each of the methods corresponding to a binary operator has a
corresponding "right" method which start with __r, for example
__radd__ :
class A:
def __init__ ( self , a): self .a = a
b = B(2 )
b.b # Out: 2
b += 1 # prints iadd b.b # Out: 3
Since there's nothing special about these methods, many other parts of
the language, parts of the standard library, and even third-party
modules add magic methods on their own, like methods to cast an object
to a type or checking properties of the object. For example, the builtin
str () function calls the object's __str__ method, if it exists. Some of these
uses are listed below.
Expression
int (a1)
abs (a1)
str (a1)
unicode (a1) (Python 2 only) repr (a1)
bool (a1)
There are also the special methods __enter__ and __exit__ for context
managers, and many more.
class Vector(object ):
# instantiation
def __init__ (self , x, y):
self .x = x self .y = y
# unary negation (-v)
def __neg__ ( self ):
return Vector( self .x , self .y) # addition (v + u)
def __add__ ( self , other):
return Vector( self .x + other.x , self .y + other.y) # subtraction (v - u)
def __sub__ ( self , other): return self + (-other) # equality (v == u)
def __eq__ ( self , other):
return self .x == other.x and self .y == other.y # abs(v)
def __abs__ ( self ):
return math .hypot( self .x , self .y) # str(v)
def __str__ ( self ):
return '<{0.x}, {0.y}>' .format( self ) # repr(v)
def __repr__ ( self ):
return 'Vector({0.x}, {0.y})' .format( self ) Now it is possible to naturally
use instances of the Vector class in various expressions.
v = Vector( 1 , 4 ) u = Vector( 2 , 0 )
u + v # Vector(3, 4)
print (u + v) # "<3, 4>" (implicit string conversion) u - v # Vector(1, -4)
u == v # False
u + v == v + u # True
abs (u + v) # 5.0
class sparselist(object ):
def __init__ (self , size):
self .size = size
self .data = {}
# l[index]
def __getitem__ ( self , index):
if index < 0 :
index + = self .size
if index >= self .size:
raise IndexError (index)
# l[index] = value
def __setitem__ ( self , index , value): self .data[index] = value
# del l[index]
def __delitem__ (self , index): if index in self .data:
l[ 12345 ] = 10
10 in l # True l[12345 ] # 10
for v in l:
pass # 0, 0, 0, ... 10, 0, 0 ... 0
class adder(object ):
def __init__ (self , first):
self .first = first
# a(...)
def __call__ ( self , second):
return self .first + second
>>> x = NotAddable(1 )
>>> y = Addable(2 )
>>> x + x
Traceback (most recent call last):
File "<stdin>" , line 1 , in < module>
TypeError : unsupported operand type (s) for +: 'NotAddable' and
'NotAddable' >>> y + y
< so.Addable object at 0x1095974d0 >
>>> z = x + y
>>> z
< so.Addable object at 0x109597510 >
>>> z.value
class Duck:
def quack( self ):
print ( "Quaaaaaack!" )
def feathers( self ):
print ( "The duck has white and gray feathers." )
class Person:
def quack( self ):
print ( "The person imitates a duck." )
def feathers(self ):
print ("The person takes a feather from the ground and shows it." )
def name(self ):
print ("John Smith" )
donald = Duck()
john = Person()
in_the_forest(donald) in_the_forest(john)
Quaaaaaack!
The duck has white and gray feathers.
The person imitates a duck.
The person takes a feather from the ground and shows it.
class Shape:
"""
This is a parent class that is intended to be inherited by other classes """
def calculate_area(self ):
"""
This method is intended to be overridden in subclasses.
If a subclass doesn't implement it but it is called, NotImplemented will be
raised. """
raise NotImplemented
class Square(Shape):
"""
This is a subclass of the Shape class, and represents a square """
side_length = 2 # in this example, the sides are 2 units long
def calculate_area(self ):
"""
This method overrides Shape.calculate_area(). When an object of type
Square has its calculate_area() method called, this is the method that will
be called, rather than the parent class' version.
class Triangle(Shape):
"""
This is also a subclass of the Shape class, and it represents a triangle """
base_length = 4
height = 3
def calculate_area(self ):
"""
This method also overrides Shape.calculate_area() and performs the
area calculation for a triangle, returning the result.
"""
def get_area(input_obj):
"""
This function accepts an input object, and will call that object's
calculate_area() method. Note that the object type is not specified. It
could be a Square, Triangle, or Shape object.
"""
print (input_obj.calculate_area())
# Now pass each object, one at a time, to the get_area() function and see
the # result.
get_area(shape_obj)
get_area(square_obj)
get_area(triangle_obj)
class Square:
side_length = 2
def calculate_square_area( self ): return self .side_length ** 2
class Triangle:
base_length = 4 height = 3
def calculate_triangle_area( self ):
return ( 0.5 * self .base_length) * self .height
def get_area(input_obj):
# Notice the type checks that are now necessary here. These type checks #
could get very complicated for a more complex example, resulting in #
duplicate and difficult to maintain code.
# Now pass each object, one at a time, to the get_area() function and see
the # result.
get_area(square_obj)
get_area(triangle_obj)
Important Note
Note that the classes used in the counter example are "new style" classes
and implicitly inherit from the object class if Python 3 is being used.
Polymorphism will work in both Python 2.x and 3.x, but the
polymorphism counterexample code will raise an exception if run in a
Python 2.x interpreter because type(input_obj).name will return
"instance" instead of the class name if they do not explicitly inherit from
object, resulting in area never being assigned to.
p = Parent() c = Child()
p.introduce() p.print_name()
c.introduce() c.print_name()
When the Child class is created, it inherits the methods of the Parent
class. This means that any methods that the parent class has, the child
class will also have. In the example, the introduce is defined for the Child
class because it is defined for Parent, despite not being defined explicitly
in the class definition of Child.
In this example, the overriding occurs when Child defines its own
print_name method. If this method was not declared, then
c.print_name() would have printed "Parent" . However, Child has
overridden the Parent's definition of print_name, and so now upon
calling c.print_name(), the word "Child" is printed.
class A(object ):
# func: A user-defined function object
#
# Note that func is a function object when it's defined,
# and an unbound method object when it's retrieved.
def func(self ):
pass
class B(object ):
# unboundMeth: A unbound user-defined method object
#
# Parent.func is an unbound user-defined method object here,
# because it's retrieved.
unboundMeth = A.func
a = A() b = B()
print A.func
# output: <unbound method A.func>
print a.func
# output: <bound method A.func of <__main__.A object at 0x10e9ab910>>
print B.unboundMeth
# output: <unbound method A.func>
print b.unboundMeth
# output: <unbound method A.func>
print A.classMethod
# output: <bound method type.classMethod of <class '__main__.A'>> print
a.classMethod
# output: <bound method type.classMethod of <class '__main__.A'>>
# Parent: The class stored in the original method object class Parent(object
):
# func: The underlying function of original method object
def func(self ):
pass
func2 = func
# False, new object created # False, new object created # False, new object
created # True, original object used
So you've just created your first class in Python, a neat little class that
encapsulates a playing card:
class Card:
def __init__ (self , suit, pips):
self .suit = suit
self .pips = pips
ace_of_spades = Card('Spades' , 1 )
four_of_clubs = Card('Clubs' , 4 )
six_of_hearts = Card('Hearts' , 6 )
That output is comprised of two important bits: the type of the object and
the object's id . The second part alone (the hexadecimal number) is
enough to uniquely identify the object at the time of the print call.[1]
What really went on was that you asked Python to "put into words" the
essence of that object and then display it to you. A more explicit version
of the same machinery might be:
string_of_card = str (ace_of_spades) print (string_of_card)
In the first line, you try to turn your Card instance into a string, and in
the second you display it.
The Problem
The issue you're encountering arises due to the fact that, while you told
Python everything it needed to know about the Card class for you to
create cards, you didn't tell it how you wanted Card instances to be
converted to strings.
And since it didn't know, when you (implicitly) wrote str (ace_of_spades),
it gave you what you saw, a generic representation of the Card instance.
The Solution (Part 1)
But we can tell Python how we want instances of our custom classes to be
converted to strings. And the way we do this is with the __str__ "dunder"
(for double-underscore) or "magic" method.
Whenever you tell Python to create a string from a class instance, it will
look for a __str__ method on the class, and call it.
Consider the following, updated version of our Card class:
class Card:
def __init__ (self , suit, pips): self .suit = suit
self .pips = pips
The __str__ method is a method, so the first argument will be self and it
should neither accept, nor be passed additional arguments.
Returning to our problem of displaying the card in a more user-friendly
manner, if we again run:
ace_of_spades = Card( 'Spades' , 1 ) print (ace_of_spades)
We'll see that our output is much better:
Ace of Spades
So great, we're done, right? Well just to cover our bases, let's double
check that we've solved the first issue we encountered, printing the list of
Card instances, the hand.
What's going on? We told Python how we wanted our Card instances to
be displayed, why did it apparently seem to forget?
The Solution (Part 2)
Well, the behind-the-scenes machinery is a bit different when Python
wants to get the string representation of items in a list. It turns out,
Python doesn't care about __str__ for this purpose.
Instead, it looks for a different method, __repr__ , and if that's not found, it
falls back on the "hexadecimal thing".[2]
So you're saying I have to make two methods to do the same thing? One for
when I want to print my card by itself and another when it's in some sort of
container?
No, but first let's look at what our class would be like if we were to
implement both __str__ and __repr__ methods:
class Card:
special_names = { 1 : 'Ace' , 11 : 'Jack' , 12 : 'Queen' , 13 : 'King' }
Here, the implementation of the two methods __str__ and __repr__ are
exactly the same, except that, to differentiate between the two methods,
(S) is added to strings returned by __str__ and (R) is added to strings
returned by __repr__ .
Note that just like our __str__ method, __repr__ accepts no arguments and
returns a string.
We can see now what method is responsible for each case:
At this point it's worth pointing out that just as we can explicitly create a
string from a custom class instance using str () as we did earlier, we can
also explicitly create a string representation of our class with a built-in
function called repr ().
For example:
str_card = str (four_of_clubs) print (str_card)
# 4 of Clubs (S)
repr_card = repr (four_of_clubs) print (repr_card)
# 4 of Clubs (R)
And additionally, if defined, we could call the methods directly (although
it seems a bit unclear and unnecessary):
print (four_of_clubs. __str__ ()) # 4 of Clubs (S)
print (four_of_clubs. __repr__ ()) # 4 of Clubs (R) About those duplicated
functions...
Python developers realized, in the case you wanted identical strings to be
returned from str () and repr () you might have to functionally-duplicate
methods -- something nobody likes.
Note this version only implements the __repr__ method. Nonetheless, calls
to str () result in the user-friendly version:
print (six_of_hearts) print ( str (six_of_hearts))
# 6 of Hearts (implicit conversion) # 6 of Hearts (explicit conversion)
as do calls to repr ():
print ([six_of_hearts]) #[6 of Hearts] (implicit conversion) print ( repr
(six_of_hearts)) # 6 of Hearts (explicit conversion) Summary
If IPython (or Jupyter ) are installed, the debugger can be invoked using:
import ipdb
ipdb.set_trace()
When reached, the code will exit and print:
ipdb >
Clearly, this means that one has to edit the code. There is a simpler way:
print divide( 1 , 2 )
Running this program will launch the interactive debugger.
python foo.py
> ~ /scratch/foo.py( 5 )divide()
- > return a/b (Pdb)
Often this command is used on one line so it can be commented out with
a single # character
import pdf ; pdb .set_trace()
At the (Pdb) prompt commands can be entered. These commands can be
debugger commands or python. To print variables we can use p from the
debugger, or python's print .
(Pdb) p a
1
(Pdb) print a 1
To see list of all local variables use
locals
build-in function
These are good debugger commands to know:
(Pdb) ! c 4
And then you need run this in terminal to connect to this process.
# Call in a terminal to see the output $ nc 127.0.0.1 4444
And you will get pdb promt
Output file
$ cat /tmp/output.tsv
name field
Dijkstra Computer Science
Shelah Math
Aumann Economic Sciences
Watch Today →
Chapter 105: Writing to CSV from String or List
Parameter open ("/path/", "mode") open (path, "mode") csv.writer(file,
delimiter)
Details
Specify the path to your CSV file
Specify mode to open file in (read, write, etc.) Pass opened CSV file here
"""
data = our list that we want to write. Split it so we get a list of lists.
"""
data = ["first_name,last_name,age" .split("," ),
"John,Doe,22" .split("," ),
"Jane,Doe,31" .split("," ),
"Jack,Reacher,27" .split("," )
]
globals
The dictionary to use for global variables. If locals is not specified, this is
also used for locals. If omitted, the globals () of calling scope are used.
A mapping object that is used for local variables. If omitted, the one
passed for globals is used locals instead. If both are omitted, then the
globals () and locals () of the calling scope are used for
globals and locals respectively.
It is not possible to use eval or exec to execute code from untrusted user
securely. Even ast.literal_eval is prone to crashes in the parser. It is
sometimes possible to guard against malicious code execution, but it
doesn't exclude the possibility of outright crashes in the parser or the
tokenizer.
Here, the input is a string of () repeated one million times, which causes a
crash in CPython parser. CPython developers do not consider bugs in
parser as security issues.
>>> variables = {'a' : 6 , 'b' : 7 } >>> eval ('a * b' , globals = variables) 42
As a plus, with this the code cannot accidentally refer to the names
defined outside:
File "<stdin>" , line 1 , in < module > File "<string>" , line 1 , in < module
NameError : name 'variables' is not defined
Using defaultdict allows for example having undefined variables set to
zero:
Installation in Windows
For Windows, pywin32 or pypiwin32 is a prerequisite. The latter is
installed automatically when pyinstaller is installed using pip.
Installation in Mac OS X
PyInstaller works with the default Python 2.7 provided with current Mac
OS X. If later versions of Python are to be used or if any major packages
such as PyQT, Numpy, Matplotlib and the like are to be used, it is
recommended to install them using either MacPorts or Homebrew .
Expand the archive and find the setup.py script. Execute python
setup.py install with administrator privilege to install or upgrade
PyInstaller.
One Folder mode can be explicitly set using the option -D or --onedir
pyinstaller myscript.py -D
Advantages:
Disadvantages
The only disadvantage of this method is that the users have to search for
the executable among a large number of files.
Also users can delete/modify other files which might lead to the app not
being able to work correctly.
# Plot the data x, y with some keyword arguments that control the plot style.
# Use two different plot commands to plot both points (scatter) and a line
(plot).
plt.scatter(x , y , c = 'blue' , marker = 'x' , s = 100 ) # Create blue markers of shape
"x" and size 100 plt.plot(x , y , color = 'red' , linewidth = 2 ) # Create a red line
with linewidth 2.
Users can install plotly library and use it offline after user
authentication. The installation of this library and offline authentication
is given here . Also, the plots can be made in Jupyter Notebooks as well.
Usage of this library requires an account with username and password.
This gives the workspace to save plots and data on the cloud.
The free version of the library has some slightly limited features and
designed for making 250 plots per day. The paid version has all the
features, unlimited plot downloads and more private data storage. For
more details, one can visit the main page here .
For documentation and examples, one can go here
N = 100
random_x = np.linspace(0 , 1 , N) random_y0 = np.random .randn(N)+5
random_y1 = np.random .randn(N) random_y2 = np.random .randn(N)5
# Create traces
trace0 = go.Scatter(
x = random_x,
y = random_y0,
mode = 'lines' ,
name = 'lines'
)
trace1 = go.Scatter(
x = random_x,
y = random_y1,
mode = 'lines+markers' , name = 'lines+markers'
)
trace2 = go.Scatter(
x = random_x,
y = random_y2,
mode = 'markers' ,
name = 'markers'
)
data = [trace0 , trace1 , trace2] ply.offline.plot(data , filename = 'line-mode'
Section 108.4: MayaVI
Y = 2 / 3 . * (cos(u) * sin(2 * v)
sqrt(2 ) * sin(u) * sin(v)) * cos(u) / (sqrt(2 )
- sin(2 * u) * sin(3 * v))
Z = -sqrt(2 ) * cos(u) * cos(u) / (sqrt(2 ) - sin(2 * u) * sin(3 * v)) S = sin(u)
If the help function is called in the console without any arguments, Python
presents an interactive help console, where you can find out about
Python modules, symbols, keywords and more.
>>> help ()
Welcome to Python 3.4 's help utility!
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/3.4/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
>>> 2 + 2
4
>>> _
4
>>> _ + 6
10
The console for the primary version of Python can usually be opened by
typing py into your windows console or python on other platforms.
$ py
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015 , 22 :44 :40 ) [MSC v.1600
64 bit (AMD64)] on win32 Type "help" , "copyright" , "credits" or
"license" for more information.
>>>
$ py
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or
"license" for more information.
Welcome!
>>>
For an object, help lists the object's docstring and the different member
functions which the object has.
>>> x = 2
>>> help (x)
Help on int object :
print_kwargs(a = "two" , b = 1 )
key = a, value = "two"
key = b, value = 1
# Note that dictionaries are unordered, so we can switch arg2 and arg3.
Only the names matter. kwargs = { "arg3" : 3 , "arg2" : "two" }
# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to
bind the others test_var_args_call( 1 , **kwargs)
def fun(**kwargs):
print kwargs.get('value' , 0 )
fun()
# print 0
fun(value= 1 ) # print 1
print_args(*a)
# 12
print_args(*b)
# 34
Note that the length of the starred argument need to be equal to the
number of the function's arguments.
A common python idiom is to use the unpacking operator * with the zip
function to reverse its effects:
a = [ 1 , 3 , 5 , 7 , 9 ] b = [ 2 , 4 , 6 , 8 , 10 ]
zipped = zip (a , b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]
zip (*zipped)
# (1,3,5,7,9), (2,4,6,8,10)
Note that the refcount increases, meaning that a and b reference the
same underlying object when they refer to the 1 primitive. However, for
larger numbers, Python actually doesn't reuse the underlying object:
>>> a = 999999999
>>> sys .getrefcount(999999999 ) 3
>>> b = 999999999
>>> sys .getrefcount(999999999 ) 3
Because the refcount for 999999999 does not change when assigning it to a
and b we can infer that they refer to two different underlying objects,
even though they both are assigned the same primitive.
>>> import gc
>>> gc .disable() # disable garbage collector
>>> class Track:
>>> foo()
Initialized
Destructed
--
Initialized
--
Destructed
To demonstrate further the concept of references:
The only time the garbage collector is needed is if you have a reference
cycle . The simples example of a reference cycle is one in which A refers
to B and B refers to A, while nothing else refers to either A or B. Neither
A or B are accessible from anywhere in the program, so they can safely
be destructed, yet their reference counts are 1 and so they cannot be
freed by the reference counting algorithm alone.
>>> A = Track()
Initialized
>>> B = Track()
Initialized
>>> A.other = B
>>> B.other = A
>>> del A; del B # objects are not destructed due to reference cycle >>> gc
.collect() # trigger collection
Destructed
Destructed
4
WARNING: doing this will leave your Python environment unstable and
prone to crashing without a traceback! Using this method could also
introduce security problems (quite unlikely) Only deallocate objects
you're sure you'll never reference again. Ever.
import ctypes
deallocated = 12345
ctypes.pythonapi._Py_Dealloc(ctypes.py_object(deallocated))
After running, any reference to the now deallocated object will cause
Python to either produce undefined behavior or crash - without a
traceback. There was probably a reason why the garbage collector didn't
remove that object... If you deallocate None , you get a special message -
Fatal Python error: deallocating None before crashing.
The with statement allows you to indent your code under the open file.
This makes it explicit and easier to see how long a file is kept open. It
also always closes a file, even if an exception is raised in the while block.
The older generations are not cleaned at each run to optimize the
process. The second and third arguments are optional and control how
frequently the older generations are cleaned. If generation0 was
processed 100 times without cleaning generation1, then generation1 will
be processed. Similarly, objects in generation2 will be processed only
when the ones in generation1 were cleaned 10 times without touching
generation2.
Details
The object which is to be stored
The open file which will contain the object
The protocol used for pickling the object (optional parameter) A bytes
object that contains a serialized object
For the simplest code, we use the dump() and load() functions.
To serialize the object
import pickle
Some data cannot be pickled. Other data should not be pickled for other
reasons.
What will be pickled can be defined in __getstate__ method. This method
must return something that is picklable. On the opposite side is
__setstate__: it will receive what __getstate__ created and has to
initialize the object.
class A( object ):
def __init__ ( self , important_data): self .important_data = important_data
Add data which cannot be pickled: self .func = lambda : 7
# Add data which should never be pickled, because it expires quickly: self
.is_up_to_date = False
def __getstate__( self ):
return [ self .important_data] # only this is needed
def __setstate__( self , state): self .important_data = state[ 0 ]
self .func = lambda : 7 # just some hard-coded unpicklable function
self .is_up_to_date = False # even if it was before pickling
Now, this can be done:
import struct
import sys
print "Native byteorder: " , sys .byteorder
# If no byteorder is specified, native byteorder is used
buffer = struct .pack("ihb" , 3 , 4 , 5 )
print "Byte chunk: " , repr (buffer)
print "Byte chunk unpacked: " , struct .unpack("ihb" , buffer)
# Last element as unsigned short instead of unsigned char ( 2 Bytes)
buffer = struct .pack("ihh" , 3 , 4 , 5 )
print "Byte chunk: " , repr (buffer)
Output:
Native byteorder: little Byte chunk: '\x03\x00\x00\x00\x04\x00\x05' Byte
chunk unpacked: (3, 4, 5) Byte chunk:
'\x03\x00\x00\x00\x04\x00\x05\x00'
You could use network byte order with data received from network or
pack data to send it to network.
import struct
# If no byteorder is specified, native byteorder is used buffer = struct
.pack("hhh" , 3 , 4 , 5 )
print "Byte chunk native byte order: " , repr (buffer) buffer = struct
.pack("!hhh" , 3 , 4 , 5 )
print "Byte chunk network byte order: " , repr (buffer)
Output:
Byte chunk native byte order: '\x03\x00\x04\x00\x05\x00' Byte chunk
network byte order: '\x00\x03\x00\x04\x00\x05'
You can optimize by avoiding the overhead of allocating a new buffer by
providing a buffer that was created earlier.
import struct
from ctypes import create_string_buffer bufferVar =
create_string_buffer(8 )
bufferVar2 = create_string_buffer(8 )
# We use a buffer that has already been created # provide format, buffer,
offset and data struct .pack_into("hhh" , bufferVar, 0 , 3 , 4 , 5 ) print "Byte
chunk: " , repr (bufferVar.raw) struct .pack_into("hhh" , bufferVar2, 2 ,
4 , 5 ) print "Byte chunk: " , repr (bufferVar2.raw)
Output:
Byte chunk: '\x03\x00\x04\x00\x05\x00\x00\x00' Byte chunk:
'\x00\x00\x03\x00\x04\x00\x05\x00'
Prefer dict .get method if you are not sure if the key is present. It allows
you to return a default value if key is not found. The traditional method
dict [key] would raise a KeyError exception.
Rather than doing
def add_student():
try :
students[ 'count' ] + = 1
except KeyError :
students[ 'count' ] = 1
Do
def add_student():
students[ 'count' ] = students.get( 'count' , 0 ) + 1
Section 114.2: Switching variables
To switch the value of two variables you can use tuple unpacking.
x = True
y = False
x, y = y, x
x
# False
y
# True
Python will implicitly convert any object to a Boolean value for testing,
so use it wherever possible.
# Good examples, using implicit truth testing
if attr:
# do something
if not attr:
# do something
# Bad examples, using specific types
if attr == 1 :
# do something
if attr == True :
# do something
if attr != '' :
# do something
# If you are looking to specifically check for None, use 'is' or 'is not'
if attr is None :
# do something
This generally produces more readable code, and is usually much safer
when dealing with unexpected types. Click here for a list of what will be
evaluated to False .
The benefit, however, comes if you decide to import your file in another
program (for example if you are writing it as part of a library). You can
then import your file, and the __main__ trap will ensure that no code is
executed unexpectedly:
# Dumping it to file
with open ( 'families.json' , 'w' ) as json_file:
json.dump(families , json_file)
# Loading it from string
json_families = json.loads(json_families)
import multiprocessing
import time
from random import randint
def countUp():
i=0
while i <= 3 :
def countDown():
i=3
while i >= 0 :
# Join the workers. This will block in the main (parent) process # until the
workers are complete.
workerUp.join()
workerDown.join()
Up: 0
Down: 3 Up: 1
Up: 2
Down: 2 Up: 3
Down: 1 Down: 0
if __name__ == "__main__" :
pool = Pool(5 )
result = pool.map (cube, [0 , 1 , 2 , 3 ])
Now that my_thread has run and terminated, calling start again will
produce a RuntimeError . If you'd like to run your thread as a daemon,
passing the daemon= True kwarg, or setting my_thread.daemon to True
before calling start(), causes your Thread to run silently in the
background as a daemon.
Joining a Thread
In cases where you split up one big job into several small ones and want
to run them concurrently, but need to wait for all of them to finish before
continuing, Thread.join() is the method you're looking for.
For example, let's say you want to download several pages of a website
and compile them into a single page. You'd do this:
import requests
from threading import Thread
from queue import Queue
q = Queue (maxsize = 20 )
def put_page_to_q(page_num):
q.put(requests.get( 'http://some-website.com/page_%s.html' %
page_num)
raise ValueError
else :
print ("Done compiling!" )
threads = []
for page_num in range (20 ):
t = Thread(target= requests.get, args= (page_num, ))
t.start()
threads.append(t)
# Next, join all threads to make sure all threads are done running before #
we continue. join() is a blocking call (unless specified otherwise using # the
kwarg blocking=False when calling join)
for t in threads:
t.join()
# Call compile() now, since all threads have completed compile (q)
A closer look at how join() works can be found here .
Create a Custom Thread Class
Using threading .Thread class we can subclass new custom Thread class.
we must override run method in a subclass.
from threading import Thread import time
class Sleepy(Thread):
def run(self ):
time .sleep(5 )
print ("Hello form Thread" )
if __name__ == "__main__" :
t = Sleepy()
t.start() # start method automatic call Thread class run method. # print
'The main program continues to run in foreground.' t.join()
print ("The main program continues to run in the foreground." )
q = Queue ()
t1 = Thread(target= consumer, args= (q, )) t2 = Thread(target=
producer, args= (q, )) t1.start()
t2.start()
def echo_server(addr):
print ('Echo server running at' , addr)
pool = ThreadPoolExecutor(128 )
sock = socket (AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5 )
while True :
This section will contain some of the most advanced examples realized
using Multithreading.
Advanced printer (logger)
A thread that prints everything is received and modifies the output
according to the terminal width. The nice part is that also the "already
written" output is modified when the width of the terminal changes.
#!/usr/bin/env python2
import threading
import Queue
import time
import sys
import subprocess
from backports.shutil_get_terminal_size import get_terminal_size
def main():
ww = line.split()
i=0
while len (new_line) <= (cols - len (ww[i]) - 1 ):
if new_line == '' :
return (line , '' )
def printer():
while True :
cols, rows = get_terminal_size() # Get the terminal dimensions msg = '#' +
'-' * (cols - 2 ) + '# \n ' # Create the try :
else :
printq.task_done()
sys .exit()
def run()
while not self ._stop_event.is_set():
print ("Still running!" )
time .sleep(2 )
print ( "stopped!"
Based on this Question .
t.start()
for t in threads:
t.join()
print ("Four runs took %.2fs" % (time .time () - start))
# Out: One run took 2.00s # Out: Four runs took 2.00s
Note that even though each process took 2 seconds to execute, the four
processes together were able to effectively run in parallel, taking 2
seconds total.
However, multithreading in cases where intensive computations are
being done in Python code - such as a lot of computation - does not result
in much improvement, and can even be slower than running in parallel:
import threading import time
def somefunc(i): return i * i
def otherfunc(m , i): return m + i
def process():
for j in range (100 ): result = 0
for i in range (100000 ):
t.start()
for t in threads:
t.join()
print ("Four runs took %.2fs" % (time .time () - start))
# Out: One run took 2.05s # Out: Four runs took 14.42s
In the latter case, multiprocessing can be effective as multiple processes
can, of course, execute multiple instructions simultaneously:
import multiprocessing import time
def somefunc(i): return i * i
def otherfunc(m , i): return m + i
def process():
for j in range (100 ):
result = 0
for i in range (100000 ):
p.start()
for p in processes:
p.join()
print ("Four runs took %.2fs" % (time .time () - start))
# Out: One run took 2.07s # Out: Four runs took 2.30s
t.join()
obj[key] = val
print ( "Obj now has %d values" % len (obj))
ts = [ threading .Thread(target = objify , args = ( str (n) , n)) for n in range
ts:
t.start()
for t in ts:
t.join()
print ("Obj final result:" )
import pprint ; pprint .pprint (obj)
# Out: Obj has 0 values
# Out: Obj has 0 values
# Out: Obj now has 1 values
# Out: Obj now has 2 valuesObj has 2 values # Out: Obj now has 3 values
# Out:
# Out: Obj has 3 values
# Out: Obj now has 4 values
# Out: Obj final result:
# Out: {'0': 0, '1': 1, '2': 2, '3': 3}
plain_num = 0
shared_num = multiprocessing.Value('d' , 0 )
lock = multiprocessing.Lock()
def increment():
global plain_num
with lock:
def countdown(count):
while count > 0 :
print ("Count value" , count) count = 1
return
if __name__ == "__main__" :
p1 = multiprocessing.Process(target= countdown, args= (10 , )) p1.start()
After a fork in a multithreaded program, the child can safely call only
async-signal-safe functions until such time as it calls execve.
(see )
Using fork, a new process will be launched with the exact same state for
all the current mutex but only the MainThread will be launched. This is
unsafe as it could lead to race conditions e.g. :
return
Because data is sensitive when dealt with between two threads (think
concurrent read and concurrent write can conflict with one another,
causing race conditions), a set of unique objects were made in order to
facilitate the passing of data back and forth between threads. Any truly
atomic operation can be used between threads, but it is always safe to
stick with Queue.
import multiprocessing
import queue
my_Queue= multiprocessing.Queue ()
#Creates a queue with an undefined maximum size
#this can be dangerous as the queue becomes increasingly large #it will
take a long time to copy data to/from each read/write thread
Most people will suggest that when using queue, to always place the
queue data in a try: except: block instead of using empty. However, for
applications where it does not matter if you skip a scan cycle (data can
be placed in the queue while it is flipping states from queue.Empty==
True to queue.Empty== False ) it is usually better to place read and write
access in what I call an Iftry block, because an 'if' statement is
technically more performant than catching the exception.
import multiprocessing
import queue
'''Import necessary Python standard libraries, multiprocessing for
classes and queue for the queue exceptions it provides'''
def Queue_Iftry_Get(get_queue, default= None , use_default= False , func
None , use_func= False ):
'''This global method for the Iftry block is provided for its reuse and
standard functionality, the if also saves on performance as opposed to
catching the exception, which is expensive.
It also allows the user to specify a function for the outgoing data to use,
and a default value to return if the function cannot return the value from
the queue''' if get_queue.empty():
if use_default:
return default
else :
try :
value = get_queue.get_nowait()
except queue.Empty:
if use_default:
return default
else :
if use_func:
return func(value)
else :
return value
def Queue_Iftry_Put(put_queue, value):
'''This global method for the Iftry block is provided because of its reuse
and
standard functionality, the If also saves on performance as opposed to
catching the exception, which is expensive.
Return True if placing value in the queue was successful. Otherwise,
false''' if put_queue.full():
return False
else :
try :
put_queue.put_nowait(value)
except queue.Full:
return False
else :
return True
def fib(n):
"""computing the Fibonacci in an inefficient way
was chosen to slow down the CPU."""
if n <= 2 :
return 1
else :
return fib(n1 )+fib(n2 )
p = multiprocessing.Pool()
print (p.map (fib, [38 , 37 , 36 , 35 , 34 , 33 ]))
#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
...
Py_BEGIN_ALLOW_THREADS
// Threaded C code
...
Py_END_ALLOW_THREADS
...
}
Section 120.3: Using Parent and Children scripts to execute
code in parallel
child.py
import time
def main():
print "starting work"
time .sleep(1 )
print "work work work work work"
time .sleep(1 )
print "done working"
if __name__ == '__main__' :
main()
parent.py
import os
def main():
for i in range ( 5 ):
os .system( "python child.py &" ) if __name__ == '__main__' : main()
ncpus = pp.size()
rank = pp.rank()
node = pp.get_processor_name()
print 'I am rank %d of %d on node %s' % (rank , ncpus , node)
if rank == 0 :
msh = 'P0'
pp.send(msg, destination= 1 )
msg = pp.receive(source= rank1 )
print 'Processor 0 received message "%s" from rank %d' % (msg, rank1
)
else :
source = rank1
destination = (rank+1 ) % ncpus
msg = pp.receive(source)
msg = msg + 'P' + str (rank)
pypar.send(msg, destination)
pp.finalize()
# We're putting together an ethernet frame here, # but you could have
anything you want instead # Have a look at the 'struct' module for more #
flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = " \x 01 \x 02 \x 03 \x 04 \x 05 \x 06"
dst_addr = " \x 01 \x 02 \x 03 \x 04 \x 05 \x 06"
payload = ("[" *30 )+"PAYLOAD" +("]" *30 )
checksum = " \x 1a \x 2b \x 3c \x 4d"
ethertype = " \x 08 \x 01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)
while True :
msg, addr = sock.recvfrom(8192 ) # This is the amount of bytes to read at
maximum print ("Got message from %s: %s" % (addr, msg))
class MyHandler(BaseRequestHandler):
def handle(self ):
print ("Got connection from: %s" % self .client_address)
msg, sock = self .request
print ("It said: %s" % msg)
sock.sendto("Got your message!" .encode(), self .client_address) # Send
reply
Sending data over the internet is made possible using multiple modules.
The sockets module provides low-level access to the underlying
Operating System operations responsible for sending or receiving data
from other computers or processes.
The following code sends the byte string b 'Hello' to a TCP server
listening on port 6667 on the host localhost and closes the connection
when finished:
Socket output is blocking by default, that means that the program will
wait in the connect and send calls until the action is 'completed'. For
connect that means the server actually accepting the connection. For
send it only means that the operating system has enough buffer space to
queue the data to be send later.
When run with the -c argument, this program connects to the server,
reads the client list, and prints it out. The client list is transferred as a
JSON string. The client name may be specified by passing the -n
argument. By passing different names, the effect on the client list may be
observed.
client_list.py
def server(client_list):
print "Starting server..."
s = socket .socket (socket .AF_INET, socket .SOCK_STREAM)
s.setsockopt(socket .SOL_SOCKET, socket .SO_REUSEADDR, 1 )
s.bind(('127.0.0.1' , 5000 ))
s.listen(5 )
while True :
def client(name):
s = socket .socket (socket .AF_INET, socket .SOCK_STREAM)
s.connect(('127.0.0.1' , 5000 ))
s.send(name)
data = s.recv(1024 )
result = json.loads(data)
print json.dumps(result, indent= 4 )
def parse_arguments():
parser = argparse.ArgumentParser()
parser .add_argument('-c' , dest= 'client' , action= 'store_true' ) parser
.add_argument('-n' , dest= 'name' , type = str , default= 'name' ) result =
parser .parse_args()
return result
def main():
client_list = dict () args = parse_arguments() if args.client:
client(args.name) else :
try :
server(client_list)
except KeyboardInterrupt : print "Keyboard interrupt"
"name1" : {
"address" : "127.0.0.1" , "port" : 62210 ,
"name" : "name1"
}
}
The receive buffers are limited to 1024 bytes. If the JSON string
representation of the client list exceeds this size, it will be truncated. This
will cause the following exception to be raised:
ValueError : Unterminated string starting at: line 1 column 1023 (char 1022
class EchoWebSocket(ClientSession):
URL = "wss://echo.websocket.org"
loop = asyncio.get_event_loop()
with EchoWebSocket() as websocket:
loop.run_until_complete(websocket.connect())
tasks = (
send(websocket), websocket.read()
)
loop.run_until_complete(asyncio.wait(tasks)) loop.close()
It is important that you port forward from your modem back, meaning
that if you have routers daisy chained to the modem, enter into the
modem's configuration settings, port forward from the modem to the
connected router, and so forth until the final router your computer is
connected to is having the information being received on modem port
9000 (in this example) forwarded to it.
import socket
import hashlib
import os
import time
import itertools
import threading
import sys
import Crypto.Cipher.AES as AES
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA
def animate():
for c in itertools .cycle([ '....' , '.......' , '..........' , '............' ]): if done:
break
sys .stdout.write(' \r CHECKING IP ADDRESS AND NOT USED PORT
' +c) sys .stdout.flush()
time .sleep(0.1 )
if check is True :
# server Quit
shutdown = False
#hashing the public key in server side for validating the hash from client
hash_object = hashlib.sha1(getpbk)
hex_digest = hash_object.hexdigest()
if getpbk != "" :
print (getpbk)
client.send("YES" )
gethash = client.recv(1024 )
print (" \n -----HASH OF PUBLIC KEY----- \n " +gethash)
if hex_digest == gethash:
# creating session key
key_128 = os .urandom(16 )
#encrypt CTR MODE session key
en = AES.new (key_128, AES.MODE_CTR, counter = lambda :key_128)
encrypto = en.encrypt(key_128)
#hashing sha1
en_object = hashlib.sha1(encrypto)
en_digest = en_object.hexdigest()
import time
import socket
import threading
import hashlib
import itertools
import sys
from Crypto import Random
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA
#animating loading
done = False
def animate():
#Setting up socket
server = socket . socket ( socket .AF_INET , socket .SOCK_STREAM)
while True :
server.send(public)
confirm = server.recv(1024 ) if confirm == "YES" :
server.send(hex_digest)
#connected msg
msg = server.recv(1024 )
en = eval (msg)
decrypt = key.decrypt(en)
# hashing sha1
en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
while True :
thread_send = threading .Thread(target = send , args = ( "------Sending
Message-----
time .sleep( 60 )
server.close()
class EchoHandler(BaseRequestHandler):
def handle(self ):
print ('connection from:' , self .client_address)
while True :
if __name__ == '__main__' :
server = TCPServer(('' , 5000 ), EchoHandler)
server.serve_forever()
Client side
class CtimeHandler(BaseRequestHandler):
def handle(self ):
print ('connection from: ' , self .client_address) # Get message and client
socket
msg, sock = self .request
resp = time .ctime()
sock.sendto(resp.encode('ascii' ), self .client_address)
if __name__ == '__main__' :
server = UDPServer(('' , 5000 ), CtimeHandler) server.serve_forever()
Testing:
while True :
connection, address = serversocket.accept()
buf = connection.recv(64 )
if len (buf) > 0 :
print (buf)
break
Client Side:
import socket
First run the SocketServer.py, and make sure the server is ready to
listen/receive sth Then the client send info to the server; After the server
received sth, it terminates
Watch Today →
Chapter 125: Python HTTP Server
Section 125.1: Running a simple HTTP server
Running this command serves the files of the current directory at port
9000 .
If no argument is provided as port number then server will run on
default port 8000 .
The -m flag will search sys .path for the corresponding .py file to run as a
module.
If you want to only serve on localhost you'll need to write a custom
Python program such as:
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
HandlerClass = SimpleHTTPRequestHandler
ServerClass = BaseHTTPServer .HTTPServer
Protocol = "HTTP/1.0"
HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address , HandlerClass)
sa = httpd.socket .getsockname()
print "Serving HTTP on" , sa[0 ], "port" , sa[1 ], "..."
httpd.serve_forever()
PORT = 8000
following:
self .send_response(200 )
self .send_header('Content-type' , 'text/html' )
self .end_headers()
def do_GET(self ):
self ._set_headers()
self .wfile.write("received get request" )
def do_POST(self ):
'''Reads post request body'''
self ._set_headers()
content_len = int (self .headers.getheader('content-length' , 0 )) post_body
= self .rfile.read(content_len)
self .wfile.write("received post request:<br>{}" .format(post_body))
host = ''
port = 80
HTTPServer((host, port), HandleRequests).serve_forever()
sa = httpd.socket .getsockname()
print "Serving HTTP on" , sa[0 ], "port" , sa[1 ], "..." httpd.serve_forever()
Hence here the port number, which the user passed as argument is
parsed and is bound to the host address. Further basic steps of socket
programming with given port and protocol is carried out. Finally socket
server is initiated.
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer | +-----------+ +------------------+
|
v
+-----------+ +--------------------+ | UDPServer |------->|
UnixDatagramServer | +-----------+ +--------------------+
@ app.route( "/about" )
def about():
return render_template( "about-us.html" )
if __name__ == "__main__" :
app.run(host = "0.0.0.0" , port = 80 , debug = True )
This will use our template file about-us.html. To ensure our application
can find this file we must organize our directory in the following format:
- application.py
/templates
- about-us.html
- login-form.html
/static
/styles
- about-style.css
- login-style.css /scripts
- about-script.js
- login-script.js
Most importantly, references to these files in the HTML must look like
this:
<link rel = "stylesheet" type = "text/css" , href = "{{url_for('static',
filename='styles/aboutstyle.css')}}" >
which will direct the application to look for about-style.css in the styles
folder under the static folder. The same format of path applies to all
references to images, styles, scripts, or files.
Running this script (with all the right dependencies installed) should
start up a local server. The host is 127.0.0.1 commonly known as
localhost. This server by default runs on port 5000. To access your
webserver, open a web browser and enter the URL localhost:5000 or
127.0.0.1:5000 (no difference). Currently, only your computer can access
the webserver.
app.run() has three parameters, host, port, and debug. The host is by
default 127.0.0.1, but setting this to 0.0.0.0 will make your web server
accessible from any device on your network using your private IP
address in the URL. the port is by default 5000 but if the parameter is set
to port 80, users will not need to specify a port number as browsers use
port 80 by default. As for the debug option, during the development
process (never in production) it helps to set this parameter to True, as
your server will restart when changes made to your Flask project.
if __name__ == "__main__" :
app.run(host = "0.0.0.0" , port = 80 , debug = True )
@ app.route( "/" )
def index():
return "You went to www.example.com" @ app.route( "/about" )
def about():
return "You went to www.example.com/about" @ app.route(
"/users/guido-van-rossum" )
return "You went to www.example.com/guido-van-rossum"
With that last route, you can see that given a URL with /users/ and the
profile name, we could return a profile. Since it would be horribly
inefficient and messy to include a @ app.route() for every user, Flask
offers to take parameters from the URL:
@ app.route( "/users/<username>" )
def profile (username):
return "Welcome to the profile of " + username cities = [ "OMAHA" ,
"MELBOURNE" , "NEPAL" , "STUTTGART" , "LIMA" , "CAIRO" ,
"SHANGHAI" ]
@ app.route( "/stores/locations/<city>" )
def storefronts(city):
if city in cities:
The two most common HTTP methods are GET and POST. Flask can
run different code from the same URL dependent on the HTTP method
used. For example, in a web service with accounts, it is most convenient
to route the sign in page and the sign in process through the same URL.
A GET request, the same that is made when you open a URL in your
browser should show the login form, while a POST request (carrying
login data) should be processed separately. A route is also created to
handle the DELETE and PUT HTTP method.
To retrieve data from the POST request, we must use the request
package:
@ app.route("/users/<username>)
def profile(username):
joinedDate = get_joined_date(username) # This function's code is
irrelevant
awards = get_awards(username) # This function's code is irrelevant
# The joinDate is a string and awards is an array of strings
return render_template(" profile .html", username=username,
joinDate=joinDate, awards=awards)
When this template is rendered, it can use the variables passed to it from
the render_template() function. Here are the contents of profile .html:
<!DOCTYPE html>
<html>
<head>
# if username
The request object provides information on the request that was made to
the route. To utilize this object, it must be imported from the flask
module:
from flask import request URL Parameters
In previous examples request.method and request.form were used,
however we can also use the request.args property to retrieve a
dictionary of the keys/values in the URL parameters.
@ app.route( "/api/users/<username>" ) def user_api(username):
try :
token = request.args.get( "key" ) if key == "pA55w0Rd" :
else :
return "User not found"
else :
Besides processing the data from the incoming message, we will also have
to Acknowledge or Reject the message. This is important, as we need to
let RabbitMQ know that we properly received and processed the
message.
def on_message(message):
"""This function is called on message received.
# Message Properties.
properties = {
'content_type' : 'text/plain' ,
'headers' : {'key' : 'value' } }
First we need to set up two basic channels, one for the main queue, and
one for the delay queue. In my example at the end, I include a couple of
additional flags that are not required, but makes the code more reliable;
such as confirm delivery, delivery_mode and durable. You can find more
information on these in the RabbitMQ manual .
After we have set up the channels we add a binding to the main channel
that we can use to send messages from the delay channel to our main
queue.
channel.queue.bind(exchange = 'amq.direct' , routing_key = 'hello' , queue
'hello' )
Next we need to configure our delay channel to forward messages to the
main queue once they have expired.
})
x-message-ttl (Message - Time To Live)
delay_channel.basic.publish(exchange = '' ,
routing_key= 'hello_delay' , body= 'test' ,
properties= {'delivery_mod' : 2 })
Once you have executed the script you should see the following queues
created in your RabbitMQ management module.
Example.
from amqpstorm import Connection
connection = Connection( '127.0.0.1' , 'guest' , 'guest' )
})
delay_channel.basic.publish(exchange = '' ,
routing_key= 'hello_delay' , body= 'test' ,
properties= {'delivery_mode' : 2 })
There are two different types of descriptors. Data descriptors are defined
as objects that define both a __get__ () and a __set__ () method, whereas
non-data descriptors only define a __get__ () method. This distinction is
important when considering overrides and the namespace of an
instance's dictionary. If a data descriptor and an entry in an instance's
dictionary share the same name, the data descriptor will take
precedence. However, if instead a non-data descriptor and an entry in an
instance's dictionary share the same name, the instance dictionary's
entry will take precedence.
To make a read-only data descriptor, define both get() and set() with the
set() raising an AttributeError when called. Defining the set() method
with an exception raising placeholder is enough to make it a data
descriptor.
descr. __get__ (self , obj, type = None ) -> value
descr.__set__ (self , obj, value) -> None
descr.__delete__ (self , obj) -> None
An implemented example:
class DescPrinter(object ):
"""A data descriptor that logs activity.""" _val = 7
def __set__ (self , obj, val): print ('Setting' , val) self ._val = val
def __delete__ (self , obj): print ('Deleting ...' ) del self ._val
class Foo():
x = DescPrinter()
i = Foo()
i.x
# Getting ... # 7
i.x = 100
# Setting 100 i.x
# Getting ... # 100
del i.x
# Deleting ... i.x
# Getting ... # 7
We pick one of the values (frequency, in Hertz) as the "anchor," i.e. the
one that can be set with no conversion, and write a descriptor class for it:
class Hertz( object ):
def __get__ ( self , instance , owner): return self .value
def __set__ ( self , instance , value): self .value = float (value)
The "other" value (period, in seconds) is defined in terms of the anchor.
We write a descriptor class that does our conversions:
class Second(object ):
def __get__ (self , instance, owner):
# When reading period, convert from frequency return 1 / instance.freq
You can create temporary files which has a visible name on the file
system which can be accessed via the name property. The file can, on
unix systems, be configured to delete on closure (set by delete param,
default is True) or can be reopened later.
The following will create and open a named temporary file and write
'Hello World!' to that file. The filepath of the temporary file can be
accessed via name, in this example it is saved to the variable path and
printed for the user. The file is then re-opened after closing the file and
the contents of the tempfile are read and printed for the user.
import tempfile
# load pandas
import pandas as pd
my_data.shape # (4, 3)
# number of rows and columns in data set
my_data.shape[ 0 ] # 4
# number of rows in data set
my_data.shape[ 1 ] # 3
# number of columns in data set
# Python uses 0-based indexing. The first row or column in a data set is
located # at position 0. In R the first row or column in a data set is located #
at position 1.
# Select the first element of the variables y and z my_data.loc[0 , ['y' , 'z' ]]
#y2
#z3
# Write the first three elements of the variables y and z # to an external file.
Here index = 0 means do not write row names.
my_data2 = my_data.loc[ 0 : 2 , [ 'y' , 'z' ]] my_data2.to_csv( 'my.output.csv'
index = 0 )
file_unzip = 'filename.zip'
unzip = zipfile .ZipFile(file_unzip, 'r' )
unzip.extractall()
unzip.close()
file_untar = 'filename.tar.gz'
untar = tarfile .TarFile(file_untar)
untar.extractall()
untar.close()
There are a few ways to inspect the contents of a zipfile. You can use the
printdir to just get a variety of information sent to stdout
with zipfile .ZipFile(filename) as zip :
zip .printdir()
# Out:
# File Name Modified Size # pyexpat.pyd 2016-06-25 22:13:34 157336 #
python.exe 2016-06-25 22:13:34 39576 # python3.dll 2016-06-25 22:13:34
51864 # python35.dll 2016-06-25 22:13:34 3127960 # etc.
We can also get a list of filenames with the namelist method. Here, we
simply print the list:
with zipfile .ZipFile(filename) as zip : print ( zip .namelist())
# Out: ['pyexpat.pyd', 'python.exe', 'python3.dll', 'python35.dll', ... etc. ...]
Instead of namelist, we can call the infolist method, which returns a list
of ZipInfo objects, which contain additional information about each file,
for instance a timestamp and file size:
# Out: pyexpat.pyd
# Out: (2016, 6, 25, 22, 13, 34) # Out: 157336
In Python 2.7 and in Python 3 versions higher than 3.2, we can use the
with context manager. We open the file in "read" mode, and then print a
list of filenames:
import zipfile
f= open ('zipfile.zip' , 'rb' ) zfile= zipfile .ZipFile(f) for cont in
zfile.namelist():
zfile.extract(cont , path)
If you want to write string of bytes into the archive you can use writestr()
method.
The gzip module provides the GzipFile class which is modeled after
Python ’s File Object. The GzipFile class reads and writes gzip-format
files, automatically compressing or decompressing the data so that it
looks like an ordinary file object.
outfilename = 'example.txt.gz'
output = gzip .open (outfilename, 'wb' )
try :
Using a list object you can create a fully functional generic Stack with
helper methods such as peeking and checking if the stack is Empty.
Check out the official python docs for using list as Stack here .
#define a stack class
class Stack :
def __init__(self) :
self. items = []
#method to check the stack is empty or not
def isEmpty(self) :
return self. items == []
#method for pushing an item
def push(self, item) :
self. items . append (item)
#method for popping an item
def pop(self) :
return self. items . pop ()
#check what item is on top of the stack without removing it
def peek(self) :
return self. items [-1]
#method to get the size
def size(self) :
return len(self. items )
#to view the entire stack
def fullStack(self) :
return self. items
An example run:
stack = Stack()
print ('Current stack:' , stack.fullStack())
print ('Stack empty?:' , stack.isEmpty())
print ('Pushing integer 1' )
stack.push(1 )
print ('Pushing string "Told you, I am generic stack!"' )
stack.push('Told you, I am generic stack!' )
print ('Pushing integer 3' )
stack.push(3 )
print ('Current stack:' , stack.fullStack())
print ('Popped item:' , stack.pop())
print ('Current stack:' , stack.fullStack())
print ('Stack empty?:' , stack.isEmpty())
Output:
Current stack: []
Stack empty?: True
Pushing integer 1
Pushing string "Told you, I am generic stack!" Pushing integer 3
Current stack: [1, 'Told you, I am generic stack!', 3] Popped item: 3
Current stack: [1, 'Told you, I am generic stack!'] Stack empty?: False
For example, the string ([]) is matching, because the outer and inner
brackets form pairs. ()<> ) is not matching, because the last ) has no
partner. ([)] is also not matching, because pairs must be either entirely
inside or outside other pairs.
def checkParenth(str ):
stack = Stack()
pushChars, popChars = "<({[" , ">)}]"
for c in str :
if c in pushChars:
stack.push(c)
elif c in popChars:
if stack.isEmpty():
return False
else :
stackTop = stack.pop()
# Checks to see whether the opening bracket matches the closing one
balancingBracket = pushChars[popChars.index(c)]
if stackTop != balancingBracket:
return False
else :
return False
VIDEO: Machine
Learning A-Z: Hands-On
Python In Data Science
Learn to create Machine Learning Algorithms in
Python from two Data Science experts. Code
templates included.
✔ Master Machine Learning on Python
✔ Have a great intuition of many Machine Learning models
✔ Make accurate predictions
✔ Make powerful analysis
✔ Make robust Machine Learning models
✔ Create strong added value to your business
✔ Use Machine Learning for personal purpose
✔ Handle specific topics like Reinforcement Learning, NLP and Deep
Learning
✔ Handle advanced techniques like Dimensionality Reduction
✔ Know which Machine Learning model to choose for each type of
problem
✔ Build an army of powerful Machine Learning models and know how
to combine them to solve any problem
Watch Today →
Chapter 135: Working around the Global
Interpreter Lock (GIL)
Section 135.1: Multiprocessing.Pool
The simple answer, when asking how to use threads in Python is: "Don't.
Use processes, instead." The multiprocessing module lets you create
processes with similar syntax to creating threads, but I prefer using their
convenient Pool object.
Using the code that David Beazley first used to show the dangers of
threads against the GIL , we'll rewrite it using multiprocessing.Pool :
David Beazley's code that showed GIL threading problems
while n > 0 :
n=1
COUNT = 10000000
import multiprocessing
import time
def countdown(n):
while n > 0 :
n=1
COUNT = 10000000
start = time . time ()
with multiprocessing.Pool as pool:
pool. map (countdown , [COUNT/ 2 , COUNT/ 2 ])
pool.close()
pool.join()
end = time . time ()
print (end-start)
I've found that, even using the with statement, if you don't close and join
the pool, the processes continue to exist. To clean up resources, I always
close and join my pools.
while n > 0 :
n=1
COUNT = 10000000
while n > 0 :
n=1
COUNT = 10000000
with nogil:
t1 = Thread(target= countdown, args= (COUNT/2 , )) t2 =
Thread(target= countdown, args= (COUNT/2 , )) start = time .time ()
t1.start(); t2.start()
t1.join(); t2.join()
Code in the body of the statement must not manipulate Python objects in
any way, and must not call anything that manipulates Python objects
without first re-acquiring the GIL. Cython currently does not check this.
package/
setup.py
test_package/
Setup.py is the standard python build file and hello.py has our single
hello_world() function.
The bld.bat, build.sh, and meta.yaml are scripts and metadata for the
Conda package. You can read the Conda build page for more info on
those three files and their purpose.
Now we create the package by running:
$ conda build test_package/
That is all it takes to create a Conda package.
The final step is uploading to binstar by copying and pasting the last line
of the print out after running the conda build test_package/ command.
On my system the command is:
$ binstar upload /home/xavier/anaconda/conda-bld/linux 64
/test_package-0.1.0-py27_0.tar. bz2
Since it is your first time creating a package and release you will be
prompted to fill out some text fields which could alternatively be done
through the web app.
You will see a done printed out to confirm you have successfully uploaded
your Conda package to Binstar.
[logger_root]
level=DEBUG
handlers=stream_handler
[handler_stream_handler] class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)
fileConfig( 'logging_config.ini' )
logger = logging .getLogger()
logger.debug('often makes a very good meal of %s' , 'visiting tourists' )
logging_config = dict (
version = 1 ,
formatters = {
'f' : {'format' :
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s' }
},
handlers = {
'h' : {'class' : 'logging.StreamHandler' ,
'formatter' : 'f' ,
'level' : logging .DEBUG}
},
root = {
'handlers' : ['h' ],
'level' : logging .DEBUG,
},
)
dictConfig(logging_config)
logger = logging .getLogger()
logger.debug( 'often makes a very good meal of %s' , 'visiting tourists' )
>>> try :
... raise Exception ('foo' ) ... except Exception as e:
... logging .exception(e)
...
ERROR:root:foo
Traceback (most recent call last):
>>> try :
... raise Exception (u'föö' )
... except Exception as e:
... logging .exception(e)
...
Traceback (most recent call last):
Trying to log an exception that contains unicode chars, this way will fail
miserably . It will hide the stacktrace of the original exception by
overriding it with a new one that is raised during formatting of your
logging .exception(e) call.
Be aware that libraries out there might throw exceptions with messages
as any of unicode or (utf-8 if you're lucky) byte-strings. If you really
need to access an exception's text, the only reliable way, that will always
work, is to use repr (e) or the %r string formatting:
>>> try :
... raise Exception (u'föö' )
... except Exception as e:
... logging .exception('received this exception: %r' % e) ...
ERROR:root:received this exception: Exception (u'f \x f6 \x f6' , )
Traceback (most recent call last):
import os , sys
def run(application):
environ['wsgi.input' ] = sys .stdin
environ['wsgi.errors' ] = sys .stderr
headers_set = []
headers_sent = []
while True :
if message_to_send:
yield "data:
{} \n\n " .format(message_to_send) "
return Response(event_stream(), mimetype=" text/event-stream ")
class Handler(sse.Handler):
@ asyncio.coroutine
def handle_request(self ):
Watch Today →
Chapter 140: Alternatives to switch statement from
other languages
Section 140.1: Use what the language o☐ers: the if/else
construct
if value == 2 :
return "two"
if value == 42 :
return "the answer to the question about life, the universe and
everything"
raise Exception ("No case found!" )
it might look redundant, and not always pretty, but that's by far the
most efficient way to go, and it does the job:
>>> switch(1 )
one
>>> switch(2 )
two
>>> switch(3 )
…
Exception : No case found!
>>> switch(42 )
the answer to the question about life the universe and everything
switch = {
1 : lambda : 'one' ,
2 : lambda : 'two' ,
42 : lambda : 'the answer of life the universe and everything' , }
then you add a default function:
def default_case():
raise Exception ( 'No case found!' )
and you use the dictionary's get method to get the function given the
value to check and run it. If value does not exists in dictionary, then
default_case is run.
you can also make some syntactic sugar so the switch looks nicer:
def run_switch(value):
return switch.get(value , default_case)()
>>> run_switch( 1 ) one
class SwitchBase:
def switch(self , case):
m = getattr (self , 'case_{}' .format(case), None ) if not m:
Another way, which is very readable and elegant, but far less efficient
than an if/else structure, is to build a class such as follows, that will read
and store the value to compare with, expose itself within the context as a
callable that will return true if it matches the stored value:
class Switch:
def __init__ ( self , value):
self ._val = value
def __enter__(self ):
return self
def __exit__(self , type , value, traceback ): return False # Allows traceback
to occur
def __call__ (self , cond, *mconds): return self ._val in (cond, )+mconds
then defining the cases is almost a match to the real switch/case construct
(exposed within a function below, to make it easier to show off):
def run_switch(value):
with Switch(value) as case:
if case( 1 ):
return 'one'
if case(2 ):
return 'two'
if case(3 ):
return 'the answer to the question about life, the universe and everything'
# default
raise Exception ('Not a case!' )
>>> run_switch(1 )
one
>>> run_switch(2 )
two
>>> run_switch(3 )
…
Exception : Not a case!
>>> run_switch(42 )
the answer to the question about life, the universe and everything
Nota Bene : This solution is being offered as the switch module available on
pypi .
a , b = (1 , 2 )
print (a)
# Prints: 1
print (b)
# Prints: 2
If you try to unpack more than the length of the iterable, you'll get an
error:
a,b,c=[1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
Python 3.x Version > 3.0
Destructuring as a list
You can unpack a list of unknown length using the following syntax:
head , *tail = [ 1 , 2 , 3 , 4 , 5 ]
Here, we extract the first value as a scalar, and the other values as a list:
print (head)
# Prints: 1
print (tail)
# Prints: [2, 3, 4, 5]
l = [1 , 2 , 3 , 4 , 5 ] head = l[0 ]
tail = l[1 :]
It also works with multiple elements or elements form the end of the list:
a , _ = [1 , 2 ]
print (a)
# Prints: 1
a, _, c = (1 , 2 , 3 ) print (a)
# Prints: 1
print (c)
# Prints: 3
Python 3.x Version > 3.0
Ignoring lists in destructuring assignments
Finally, you can ignore many values using the *_ syntax in the
assignment:
a , *_ = [1 , 2 , 3 , 4 , 5 ] print (a)
# Prints: 1
which is not really interesting, as you could using indexing on the list
instead. Where it gets nice is to keep first and last values in one
assignment:
a , _, b, _, c, *_ = [1 , 2 , 3 , 4 , 5 , 6 ] print (a, b, c)
# Prints: 1 3 5
But you can also use the destructuring syntax to pack arguments up, so
you can assign variables using a list or a dict .
Packing a list of arguments
Consider you have a list of values
l=[1,2,3]
You can call the function with the list of values as an argument using the
* syntax:
fun1(*l)
# Returns: (1,2,3)
fun1(*['w' , 't' , 'f' ]) # Returns: ('w','t','f')
But if you do not provide a list which length matches the number of
arguments:
fun1(*[ 'oops' ])
# Raises: TypeError: fun1() missing 2 required positional arguments:
'arg2' and 'arg3'
Packing keyword arguments
Now, you can also pack arguments using a dictionary. You can use the **
operator to tell Python to unpack the dict as parameter values:
d={
'arg1' : 1 ,
'arg2' : 2 ,
'arg3' : 3
}
fun1(**d)
# Returns: (1, 2, 3)
when the function only has positional arguments (the ones without
default values) you need the dictionary to be contain of all the expected
parameters, and have no extra parameter, or you'll get an error:
For functions that have optional arguments, you can pack the arguments
as a dictionary the same way:
fun2(**d)
# Returns: (1, 2, 3)
But there you can omit values, as they will be replaced with the defaults:
fun2(**{ 'arg2' : 2 }) # Returns: ('a', 2, 'c')
And the same as before, you cannot give extra values that are not
existing parameters:
fun2(**{ 'arg1' : 1 , 'arg2' : 2 , 'arg3' : 3 , 'arg4' : 4 })
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
In real world usage, functions can have both positional and optional
arguments, and it works the same:
def fun3(arg1 , arg2 = 'b' , arg3 = 'c' ) return (arg1 , arg2 , arg3)
you can call the function with just an iterable:
fun3(*[ 1 ])
# Returns: (1, 'b', 'c') fun3(*[1 , 2 , 3 ])
# Returns: (1, 2, 3)
fun3(**{ 'arg1' :1 })
# Returns: (1, 'b', 'c')
fun3(**{'arg1' :1 , 'arg2' :2 , 'arg3' :3 }) # Returns: (1, 2, 3)
fun1( 1 , 2 , 3 )
# Prints: (1, 2, 3) {}
fun1(a= 1 , b= 2 , c= 3 )
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x' , 'y' , 'z' , a= 1 , b= 2 , c= 3 )
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}
class MyString(str ):
def __init__ (self , *args, **kwarg):
print ('Constructing MyString' )
super (MyString, self ).__init__ (*args, **kwarg)
def fib(n):
if n <= 2 : return 1
return fib(n1 ) + fib(n2 )
# Display the disassembled bytecode of the function.
dis . dis (fib)
The function dis . dis in the dis module will return a decompiled bytecode
of the function passed to it.
Print full path of the file where the method random .randint is defined:
import dill
print dill.source.getsource(add) # def add(a, b):
return a + b
Built-in objects
The source code for Python's built-in functions is written in c and can
only be accessed by looking at the Python's source code (hosted on
Mercurial or downloadable from
https://www.python.org/downloads/source/) .
print ( inspect .getsource( sorted )) # raises a TypeError type ( sorted ) # <class
'builtin_function_or_method'>
def fib(n):
if n <= 2 : return 1
return fib(n1 ) + fib(n2 )
dir (fib.__code__)
def fib(n):
if n <= 2 : return 1
return fib(n1 ) + fib(n2 )
dir (fib.__code__)
For instance, say you have the classes Car, Boat, and Plane. Objects
from all of these classes have the ability to travel, so they get the function
travel. In this scenario, they all travel the same basic way, too; by getting
a route, and moving along it. To implement this function, you could
derive all of the classes from Vehicle, and put the function in that shared
class:
The important thing with mixins is that they allow you to add
functionality to much different objects, that don't share a "main"
subclass with this functionality but still share the code for it nonetheless.
Without mixins, doing something like the above example would be much
harder, and/or might require some repetition.
Mixins are a sort of class that is used to "mix in" extra properties and
methods into a class. This is usually fine because many times the mixin
classes don't override each other's, or the base class' methods. But if you
do override methods or properties in your mixins this can lead to
unexpected results because in Python the class hierarchy is defined right
to left.
We see the result returned is from the Base class. This can lead to
unexpected errors in the logic of your code and needs to be accounted for
and kept in mind
class Book:
def __init__ (self , title, author):
self .title = title
self .author = author
>>> book1.series
Traceback (most recent call last):
File "<stdin>" , line 1 , in < module>
AttributeError : 'Book' object has no attribute 'series'
class Book:
def __init__ (self , title, author):
self .title = title
self .author = author
In the example above, it's easy to see what happens if we create a new
Book that contains a title and a author. If all books we're to add to our
Library have authors and titles, then we can skip the getters and setters
and use the dot notation. However, suppose we have some books that do
not have an author and we want to set the author to "Unknown". Or if
they have multiple authors and we plan to return a list of authors.
In this case we can create a getter and a setter for the author attribute.
class P:
def __init__ (self , title, author): self .title = title
self .setAuthor(author)
@ property
def author( self ):
return self .__author @ author.setter
def author( self , author):
if not author:
Note, normally Python doesn't allow you to have multiple methods with
the same name and different number of parameters. However, in this
case Python allows this because of the decorators used.
If we test the code:
Watch Today →
Chapter 145: ArcPy
Section 145.1: createDissolvedGDB to create a file gdb on the
workspace
def createDissolvedGDB(workspace , gdbName):
gdb_name = workspace + "/" + gdbName + ".gdb"
if (arcpy.Exists(gdb_name):
arcpy.Delete_management(gdb_name)
arcpy.CreateFileGDB_management(workspace, gdbName, "" )
else :
arcpy.CreateFileGDB_management(workspace , gdbName , "" )
return gdb_name
Section 145.2: Printing one field's value for all rows of feature
class in file geodatabase using Search Cursor
To print a test field (TestField) from a test feature class (TestFC) in a test
file geodatabase (Test.gdb) located in a temporary folder (C:\Temp):
with arcpy.da.SearchCursor(r "C: \T emp \T est.gdb \T estFC" , [ "TestField"
]) as cursor: for row in cursor:
print row[ 0 ]
Abstract classes are classes that are meant to be inherited but avoid
implementing specific methods, leaving behind only method signatures
that subclasses must implement.
Abstract classes are useful for defining and enforcing class abstractions
at a high level, similar to the concept of interfaces in typed languages,
without the need for method implementation.
class Fruit:
def check_ripeness( self ):
raise NotImplementedError ( "check_ripeness method not implemented!"
)
class Apple(Fruit): pass
a = Apple()
a.check_ripeness() # raises NotImplementedError
class AbstractClass(object ):
# the metaclass attribute must always be set as a class variable
__metaclass__ = ABCMeta
class MontyPython:
def joke( self ):
raise NotImplementedError () def punchline( self ):
raise NotImplementedError ()
class ArgumentClinic(MontyPython): def joke( self ):
return "Hahahahahah" When we instantiate an object and call it's two
methods, we'll get an error (as expected) with the punchline() method.
>>> sketch = ArgumentClinic() >>> sketch.punchline()
NotImplementedError
However, this still allows us to instantiate an object of the
ArgumentClinic class without getting an error. In fact we don't get an
error until we look for the punchline().
This is avoided by using the Abstract Base Class (ABC) module. Let's see
how this works with the same example:
from abc import ABCMeta , abstractmethod
pass
@ abstractmethod
def punchline( self ): pass
class ArgumentClinic(MontyPython): def joke( self ):
return "Hahahahahah" This time when we try to instantiate an object
from the incomplete class, we immediately get a TypeError!
>>> c = ArgumentClinic()
TypeError :
"Can't instantiate abstract class ArgumentClinic with abstract methods
punchline"
In this case, it's easy to complete the class to avoid any TypeErrors:
class ArgumentClinic(MontyPython): def joke( self ):
return "Hahahahahah" def punchline( self ):
return "Send in the constable!" This time when you instantiate an object
it works!
When we use more than one mixins, Order of mixins are important. here
is a simple example:
class Mixin1( object ):
def test ( self ):
print "Mixin1"
class Mixin2( object ):
def test ( self ):
print "Mixin2"
class MyClass(Mixin1 , Mixin2):
pass
In this example we call MyClass and test method,
Result must be Mixin1 because Order is left to right. This could be show
unexpected results when super classes add with it. So reverse order is
more good just like this:
class MyClass(Mixin2 , Mixin1): pass
Result will be:
class PluginA(Base):
def test (self ):
super ().test ()
print ("Plugin A." )
class PluginB(Base):
def test (self ):
super ().test () print ("Plugin B." )
Results:
foo = "bar"
foo[ 0 ] = "c" # Error
Immutable variable value can not be changed once they are created.
Second line would return an error since frozenset members once created
aren't assignable. Third line would return error as frozensets do not
support functions that can manipulate members.
For example:
Code Python 2 output Python 3 output
3 / 2 1 1.5
2 / 3 0 0.6666666666666666
-3 / 2 -2 -1.5
There is also the floor division operator (//), which works the same way
in both versions: it rounds down to the nearest integer. (although a float
is returned when used with floats) In both versions the // operator maps
to __floordiv__ .
One can explicitly enforce true division or floor division using native
functions in the operator module:
See PEP 238 for more detailed rationale why the division operator was
changed in Python 3 and why old-style division should be avoided.
See the Simple Math topic for more about division.
Note: When using the *variable syntax, the variable will always be a list,
even if the original type wasn't a list. It may contain zero or more
elements depending on the number of elements in the original list.
first , second , *tail , last = [ 1 , 2 , 3 , 4 ] print (tail)
# Out: [3]
# Works in Python 2, but syntax error in Python 3: map (lambda (x, y): x +
y, zip (range (5 ), range (5 ))) # Same is true for non-lambdas:
def example((x, y)):
pass
x , y = x_y
pass
See PEP 3113 for detailed rationale.
# Or, if you really need a byte string: s = b'Cafe' # type(s) == bytes s = 'Café'
.encode() # type(s) == bytes
# Output in Python 2
# Hi, my name is Łukasz Langa. # .agnaL zsaku Ł si eman ym ,iH # .agnaL
zsaku �� si eman ym ,iH
# Output in Python 3
# Hi, my name is Łukasz Langa. # .agnaL zsaku Ł si eman ym ,iH # .agnaL
zsaku Ł si eman ym ,iH
# print a newline
# add trailing comma to remove newline # print to stderr
# print "hello", since ("hello") == "hello" # print an empty tuple "()"
# print space-separated arguments: "1 2 3" # print tuple "(1, 2, 3)"
# print(xrange(1, 10))
# The output will be:
#Traceback (most recent call last): # File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined
Additionally, since Python 3.2, range also supports slicing, index and
count:
# range(10000000000000000)
# The output would be:
# Traceback (most recent call last): # File "<stdin>", line 1, in <module> #
MemoryError
print ( xrange ( 100000000000000000 )) # Out: xrange(100000000000000000)
Since the latter behaviour is generally desired, the former was removed
in Python 3. If you still want to have a list in Python 3, you can simply
use the list () constructor on a range object:
Python 3.x Version ≥ 3.0
print ( list ( range ( 1 , 10 )))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Compatibility
In order to maintain compatibility between both Python 2.x and Python
3.x versions, you can use the builtins module from the external package
future to achieve both forward-compatibility and backward-compatibility :
for i in range ( 10 ** 8 ):
pass
try :
raise IOError , "input/output error"
except IOError , exc:
print exc
The above exception was the direct cause of the following exception:
The traceback is
try : funcWithError()
except :
sys_vers = getattr (sys , 'version_info' , (0 , )) if sys_vers < (3 , 0 ):
traceback .print_exc()
raise Exception ("new exception" )
Or in order to make it compatible with both Python 2 and 3 you may use
the six package like so:
import six try :
file = open ( 'database.db' )
except FileNotFoundError as e:
six.raise_from(DatabaseError( 'Cannot open {}' ) , None )
Section 149.7: Leaked variables in list comprehension
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U']
print (x)
# Out: 'U'
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U'] print (x)
# Out: 'hello world!'
As can be seen from the example, in Python 2 the value of x was leaked:
it masked hello world ! and printed out U, since this was the last value of x
when the loop ended.
However, in Python 3 x prints the originally defined hello world ! , since
the local variable from the list comprehension does not mask variables
from the surrounding scope.
Additionally, neither generator expressions (available in Python since
2.5) nor dictionary or set comprehensions (which were backported to
Python 2.7 from Python 3) leak variables in Python 2.
Note that in both Python 2 and Python 3, variables will leak into the
surrounding scope when using a for loop:
True # False
False # True
You can't do this with None since Python 2.4.
Python 2.x Version ≥ 2.4
None = None # SyntaxError: cannot assign to None
In Python 3, True , False , and None are now keywords.
Python 3.x Version ≥ 3.0
True , False = False , True # SyntaxError: can't assign to keyword None = None
# SyntaxError: can't assign to keyword
try :
input = raw_input
except NameError :
pass
[ 1 , 2 ] > 'foo'
# Out: False
(1 , 2 ) > 'foo'
# Out: True
[1 , 2 ] > (1 , 2 )
# Out: False
100 < [1 , 'x' ] < 'xyz' < (1 , 'x' )
# Out: True
This was originally done so a list of mixed types could be sorted and
objects would be grouped together by type:
[ 1 , 2 ] > 'foo'
# TypeError: unorderable types: list() > str() (1 , 2 ) > 'foo'
# TypeError: unorderable types: tuple() > str() [1 , 2 ] > (1 , 2 )
# TypeError: unorderable types: list() > tuple()
Using str as the key function temporarily converts each item to a string
only for the purposes of comparison. It then sees the string
representation starting with either [, ', { or 0 -9 and it's able to sort those
(and all the following characters).
g = (i for i in range (0 , 3 ))
g.next() # Yields 0
g.next() # Yields 1
g.next() # Yields 2
Since Python 2 itertools . izip is equivalent of Python 3 zip izip has been
removed on Python 3.
test.test_support test.support
Tkinter tkinter
tkFileDialog tkinter.filedialog
urllib / urllib2 urllib, urllib.parse, urllib.error, urllib.response,
urllib.request, urllib.robotparser
Some modules have even been converted from files to libraries. Take
tkinter and urllib from above as an example.
Compatibility
When maintaining compatibility between both Python 2.x and 3.x
versions, you can use the future external package to enable importing top-
level standard library packages with Python 3.x names on Python 2.x
versions.
>>> 1 <> 2
True
>>> 1 <> 1
False
>>> foo = 'hello world'
>>> repr (foo)
"'hello world'"
>>> `foo`
"'hello world'"
>>> 1 <> 2
File "<stdin>" , line 1
1 <> 2
^
SyntaxError : invalid syntax
>>> `foo`
File "<stdin>" , line 1
`foo`
^
SyntaxError : invalid syntax
>>> 2 **31
2147483648L
>>> type (2 **31 )
< type 'long' >
>>> 2 **30
1073741824
>>> type (2 **30 )
< type 'int' >
>>> 2 **31 - 1 # 2**31 is long and long - int is long 2147483647L
However, in Python 3, the long data type was removed; no matter how big
the integer is, it will be an int .
Python 3.x Version ≥ 3.0
2 **1024
# Output:
1797693134862315907729305190789024733617976978942306572734300811577326758
1120113879871393357658789768814416622492847430639474124377767893424865485
5208500576883815068234246288147391311054082723716335051068458629823994724
137216
print (-(2 **1024 ))
# Output:
-179769313486231590772930519078902473361797697894230657273430081157732675
2112011387987139335765878976881441662249284743063947412437776789342486548
9520850057688381506823424628814739131105408272371633505106845862982399472
4137216
type (2 **1024 )
# Output: <class 'int'>
>>> my_list = [1 , 2 , 3 , 4 , 5 ]
>>> import operator , functools
>>> functools.reduce (operator .truediv, my_list) 0.008333333333333333
We can also use from functools import reduce to avoid calling reduce with
the namespace name.
shapes
├── __init__ .py |
├── circle.py |
├── square.py |
└── triangle.py
shapes
├── __init__ .py |
├── circle
│ ├── __init__ .py │ └── circle.py |
├── square
│ ├── __init__ .py │ └── square.py |
├── triangle
│ ├── __init__ .py │ ├── triangle.py |
└── util.py
# Python 2.X
>>> map (str , [1 , 2 , 3 , 4 , 5 ])
['1' , '2' , '3' , '4' , '5' ]
>>> type (_)
>>> < class 'list' >
# Python 3.X
>>> map (str , [1 , 2 , 3 , 4 , 5 ])
< map object at 0x*>
>>> type (_)
< class 'map' >
In Python 3 however, round () will return the even integer (aka bankers'
rounding ). For example:
Python 3.x Version ≥ 3.0
round (1.5 ) # Out: 2 round (0.5 ) # Out: 0 round (0.5 ) # Out: 0 round (1.5
# Out: -2
The round() function follows the half to even rounding strategy that will
round half-way numbers to the nearest even integer (for example, round (
2.5 ) now returns 2 rather than 3.0).
As per reference in Wikipedia , this is also known as unbiased rounding ,
convergent rounding , statistician's rounding , Dutch rounding , Gaussian
rounding , or odd-even rounding .
Half to even rounding is part of the IEEE 754 standard and it's also the
default rounding mode in Microsoft's .NET.
This rounding strategy tends to reduce the total rounding error. Since on
average the amount of numbers that are rounded up is the same as the
amount of numbers that are rounded down, rounding errors cancel out.
Other rounding methods instead tend to have an upwards or downwards
bias in the average error. round() return type
The round () function returns a float type in Python 2.7
Python 2.x Version ≤ 2.7 round ( 4.8 )
# 5.0
Starting from Python 3.0, if the second argument (number of digits) is
omitted, it returns an int .
Python 3.x Version ≥ 3.0 round ( 4.8 )
#5
import io
assert io.open is open # the builtin is an alias
buffer = io.StringIO ()
buffer.write('hello, ' ) # returns number of characters written
buffer.write('world! \n ' )
buffer.getvalue() # 'hello, world!\n'
The file mode (text vs binary) now determines the type of data produced
by reading a file (and type required for writing):
In Python 3 the cmp built-in function was removed, together with the
__cmp__ special method.
From the documentation:
Moreover all built-in functions that accepted the cmp parameter now only
accept the key keyword only parameter.
In the functools module there is also useful function cmp_to_key ( func ) that
allows you to convert from a cmp -style function to a key-style function:
exec ('code' )
exec ('code' , global_vars)
exec ('code' , global_vars, local_vars)
and the latter forms are guaranteed to work identically in both Python 2
and Python 3.
"1deadbeef3" .decode('hex' )
# Out: '\x1d\xea\xdb\xee\xf3'
' \x 1d \x ea \x db \x ee \x f3' .encode('hex' )
# Out: 1deadbeef3
"1deadbeef3" .decode('hex' )
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'str' object has no attribute 'decode'
b "1deadbeef3" .decode('hex' )
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# LookupError: 'hex' is not a text encoding; use codecs.decode() to handle
arbitrary codecs
However, as suggested by the error message, you can use the codecs
module to achieve the same result:
import codecs
codecs .decode('1deadbeef4' , 'hex' )
# Out: b'\x1d\xea\xdb\xee\xf4'
codecs .encode(b' \x 1d \x ea \x db \x ee \x f4' , 'hex' ) # Out: b'1deadbeef4'
Note that codecs . encode returns a bytes object. To obtain a str object just
decode to ASCII:
codecs .encode(b ' \x 1d \x ea \x db \x ee \x ff' , 'hex' ).decode( 'ascii' ) # Out:
'1deadbeeff'
Porting Python 2 code that iterates over dictionary keys, values or items
while mutating it is sometimes tricky. Consider:
d = { 'a' : 0 , 'b' : 1 , 'c' : 2 , '!' : 3 } for key in d.keys():
if key.isalpha():
del d[key]
The code looks as if it would work similarly in Python 3, but there the
keys method returns a view object, not a list, and if the dictionary
changes size while being iterated over, the Python 3 code will crash with
RuntimeError : dictionary changed size during iteration. The solution is
of course to properly write for key in list (d).
Similarly, view objects behave differently from iterators: one cannot use
next() on them, and one cannot resume iteration; it would instead
restart; if Python 2 code passes the return value of d.iterkeys(),
d.itervalues() or d.iteritems() to a method that expects an iterator instead
of an iterable , then that should be iter (d), iter (d.values()) or iter
(d.items()) in Python 3.
my_instance = MyClass()
print bool (MyClass) # True print bool (my_instance) # False
class MyClass:
def __bool__(self ): return False
my_instance = MyClass()
print (bool (MyClass)) # True print (bool (my_instance)) # False
class A(object ):
@ property
def get(self ):
raise IOError
class B(object ):
@ property
def get(self ):
try : a.get
except AttributeError :
print ("no get property!" )
else :
print ( "no get property!" )
-j PROCESSES, --processes=PROCESSES
-x NOFIX, --nofix=NOFIX
-l, --list-fixes
-p, --print-function
-v, --verbose
--no-diffs
-w
-n, --nobackups
-o OUTPUT_DIR, --output
dir=OUTPUT_DIR
-W, --write-unchanged-files
--add-suffix=ADD_SUFFIX
Description
2to3 accepts a list of files or directories which is to be transformed as its
argument. The directories are recursively traversed for Python sources.
Option Description
Specify transformations to be applied; default: all. List available
transformations with --list-fixes
Run 2to3 concurrently
Exclude a transformation
List available transformations
Change the grammar so that print () is considered a function More
verbose output
Do not output diffs of the refactoring
Write back modified files
Do not create backups of modified files
Place output files in this directory instead of overwriting input files.
Requires the -n flag, as backup files are unnecessary when the input files
are not modified.
Write output files even is no changes were required. Useful with -o so
that a complete source tree is translated and copied. Implies -w. Specify
a string to be appended to all output filenames. Requires -n if non-
empty. Ex.: --add-suffix= '3' will generate .py3 files.
In the above file, there are several incompatible lines. The raw_input ()
method has been replaced with input () in Python 3.x and print is no
longer a statement, but a function. This code can be converted to Python
3.x code using the 2to3 tool.
Unix
$ 2to3 example.py
Windows
> path/to/2to3.py example.py
Running the above code will output the differences against the original
source file as shown below.
def greet(name):
- print "Hello, {0}!" .format(name)
-print "What's your name?"
-name = raw_input ()
+ print ("Hello, {0}!" .format(name))
+print ("What's your name?" )
+name = input ()
greet(name)
RefactoringTool: Files that need to be modified: RefactoringTool:
example.py
The modifications can be written back to the source file using the -w flag.
A backup of the original file called example.py.bak is created, unless the
-n flag is given.
Unix
$ 2to3 -w example.py
Windows
> path/to/2to3.py -w example.py
Now the example.py file has been converted from Python 2.x to Python
3.x code.
Once finished, example.py will contain the following valid Python3.x
code:
Python 3.x Version ≥ 3.0
def greet(name):
print ("Hello, {0}!" .format(name))
print ("What's your name?" )
name = input ()
greet(name)
Hello World
print "Hello World!"
You can also use .NET functions:
import clr
from System import Console
Console.WriteLine("Hello World!" )
External links
Official website
GitHub repository
Hello World
print "Hello World!"
You can also use Java functions:
from java.lang import System System.out.println( "Hello World!" )
External links
Official website
Mercurial repository
<p>
<div id = "greet" >...</div>
<button onclick = "hello.solarSystem.greet ()" >Click me repeatedly!
</button>
<p>
<div id = "explain" >...</div>
<button onclick = "hello.solarSystem.explain ()" >And click me
repeatedly too!</button>
class SolarSystem:
planets = [ list ( chain ( planet, ( index + 1 ,))) for index, planet in
enumerate (( ( 'Mercury' , 'hot' , 2240 ),
( 'Venus' , 'sulphurous' , 6052 ),
( 'Earth' , 'fertile' , 6378 ),
( 'Mars' , 'reddish' , 3397 ),
( 'Jupiter' , 'stormy' , 71492 ),
( 'Saturn' , 'ringed' , 60268 ),
( 'Uranus' , 'cold' , 25559 ),
( 'Neptune' , 'very cold' , 24766 )
))]
lines = (
'{} is a {} planet' ,
'The radius of {} is {} km' ,
'{} is planet nr. {} counting from the sun'
)
def __init__ ( self ): self. lineIndex = 0
class B:
def __init__ (self , y):
alert ('In B constructor' ) self .y = y
a = A ( 1001 )
a.show ( 'america' )
b = B ( 2002 )
b.show ( 'russia' )
c = C ( 3003 , 4004 ) c.show ( 'netherlands' )
show2 = c.show show2 ( 'copy' )
JavaScript
var A = __class__ ( 'A' , [ object ] , {
get __init__ () { return __get__ (this , function ( self , x) { self .x = x ;
}) ; } ,
get show () { return __get__ (this , function ( self , label) { print ( 'A.show'
self .x) ;
}) ; }
});
var B = __class__ ('B' , [object ], {
}) ; } ,
get show () { return __get__ (this , function ( self , label) { print ( 'B.show'
self .y) ;
}) ; }
});
var C = __class__ ('C' , [A, B], {
}) ; },
get show () {return __get__ (this, function (self , label) { B.show (self ,
label);
print ('C.show' , label, self .x, self .y);
}); }
});
var a = A (1001 );
a.show ('america' );
var b = B (2002 );
b.show ('russia' );
var c = C (3003 , 4004 );
c.show ('netherlands' );
var show2 = c.show;
show2 ('copy' );
External links
Official website: http://www.transcrypt.org/ Repository:
https://github.com/JdeH/Transcrypt
This analyzes a python script and, for each defined function, reports the
line number where the function began, where the signature ends, where
the docstring ends, and where the function definition ends.
#!/usr/local/bin/python3
import ast
import sys
""" The data we collect. Each key is a function name; each value is a dict
with keys: firstline, sigend, docend, and lastline and values of line
numbers where that happens. """
functions = {}
def process(functions):
""" Handle the function data stored in functions. """
for funcname, data in functions.items():
class FuncLister(ast.NodeVisitor):
def visit_FunctionDef(self , node):
""" Recursively visit all functions, determining where each function
starts, where its signature ends, where the docstring ends, and where the
function ends. """
functions[node.name] = {'firstline' :node.lineno}
sigend = max (node.lineno, lastline(node.args))
functions[node.name]['sigend' ] = sigend
docstring = ast.get_docstring(node)
docstringlength = len (docstring.split(' \n ' )) if docstring else 1
functions[node.name]['docend' ] = sigend+docstringlength
functions[node.name]['lastline' ] = lastline(node)
self .generic_visit(node)
def lastline(node):
""" Recursively find the last line of a node """
return max ( [ node.lineno if hasattr (node, 'lineno' ) else 1 , ]
def readin(pythonfilename):
""" Read the file name and store the function data into functions. """
with open (pythonfilename) as f:
code = f.read()
FuncLister().visit(ast.parse( code ))
if __name__ == '__main__' :
if len ( sys .argv) > 1 :
for file in sys .argv[ 1 :]: analyze( file , process) else :
analyze( sys .argv[ 0 ] , process)
errors
The errors mode, e.g. 'replace' to replace bad characters with question
marks, 'ignore' to ignore bad characters, etc...
Decoding
Morale
It is clear from the above that it is vital to keep your encodings straight
when dealing with unicode and bytes.
Section 153.2: File I/O
Files opened in a non-binary mode (e.g. 'r' or 'w' ) deal with strings. The
default encoding is 'utf8' .
open (fn , mode = 'r' ) # opens file for reading in utf8 open (fn , mode = 'r'
encoding = 'utf16' ) # opens file for reading utf16
# ERROR: cannot write bytes when a string is expected:
open ( "foo.txt" , "w" ).write(b "foo" )
Files opened in a binary mode (e.g. 'rb' or 'wb' ) deal with bytes. No
encoding argument can be specified as there is no encoding.
open (fn , mode = 'wb' ) # open file for writing bytes
# ERROR: cannot write string when bytes is expected: open (fn , mode = 'wb'
).write( "hi" )
In Python 3 str is the type for unicode-enabled strings, while bytes is the
type for sequences of raw bytes.
type ( "f" ) == type (u "f" ) # True, <class 'str'>
type (b "f" ) # <class 'bytes'>
In Python 2 a casual string was a sequence of raw bytes by default and
the unicode string was every string with "u" prefix.
type ( "f" ) == type (b "f" ) # True, <type 'str'> type (u "f" ) # <type 'unicode'>
Unicode to bytes
Unicode strings can be converted to bytes with .encode(encoding).
Python 3
Python 2
in py2 the default console encoding is sys .getdefaultencoding() == 'ascii'
and not utf 8 as in py3, therefore printing it as in the previous example is
not directly possible.
>>> print type (u"£13.55" .encode('utf8' )) < type 'str' >
>>> print u"£13.55" .encode('utf8' )
SyntaxError : Non-ASCII character ' \x c2' in ...
Bytes to unicode
Bytes can be converted to unicode strings with .decode(encoding).
A sequence of bytes can only be converted into a unicode string via the
appropriate encoding!
>>> b ' \x c2 \x a313.55' .decode( 'utf8' ) '£13.55'
If the encoding can't handle the string, a UnicodeDecodeError is raised:
>>> b ' \x c2 \x a313.55' .decode( 'utf16' )
import serial
#Serial takes these two parameters: serial device and baudrate
ser = serial.Serial('/dev/ttyUSB0' , 9600 )
import serial
#Serial takes two parameters: serial device and baudrate ser =
serial.Serial('/dev/ttyUSB0' , 9600 )
results = News.objects.todays_news()
for r in results:
article = graph.merge_one("NewsArticle" , "news_id" , r)
article.properties["title" ] = results[r]['news_title' ]
article.properties["timestamp" ] = results[r]['news_timestamp' ]
article.push()
[...]
results = News.objects.todays_news()
for r in results:
article = graph.merge_one("NewsArticle" , "news_id" , r)
if 'LOCATION' in results[r].keys():
for loc in results[r]['LOCATION' ]:
loc = graph.merge_one("Location" , "name" , loc)
try :
rel = graph.create_unique(Relationship(article, "about_place" , loc))
except Exception , e:
print e
def get_autocomplete(text):
query = """
start n = node(*) where n.name =~ '(?i)%s.*' return n.name,labels(n)
limit 10; """
# print res[0],res[1]
obj.append({ 'name' :res[ 0 ] , 'entity_type' :res[ 1 ]}) return res
This is a sample cypher query to get all nodes with the property name
that starts with the argument text.
Search for other People / Locations connected to the same news articles
as Trump with at least 5 total relationship nodes.
main(scr , *args):
# -- Perform an action with Screen -
scr.border(0 )
scr.addstr(5 , 5 , 'Hello from Curses!' , curses .A_BOLD)
scr.addstr(6 , 5 , 'Press q to close this screen' , curses .A_NORMAL)
while True :
# stay in this loop till the user presses 'q'
ch = scr.getch()
if ch == ord ('q' ):
curses .wrapper(main)
Here, wrapper will initialize curses, create stdscr, a WindowObject and
pass both stdscr, and any further arguments to func. When func returns,
wrapper will restore the terminal before the program exits.
try : # -- Initialize -
stdscr = curses .initscr() curses .noecho()
curses .cbreak()
stdscr.keypad( 1 )
while True :
# stay in this loop till the user presses 'q' ch = stdscr.getch()
if ch == ord ('q' ):
break
# -- End of user code -
except :
traceback .print_exc() # print trace back log of the error
finally :
# --- Cleanup on exit -- stdscr.keypad(0 )
curses .echo()
curses .nocbreak()
curses .endwin()
Output:
Simon bought 2 candy for 8 dollar
Templates support $-based substitutions instead of %-based
substitution. Substitute (mapping, keywords) performs template
substitution, returning a new string.
Mapping is any dictionary-like object with keys that match with the
template placeholders. In this example, price and qty are placeholders.
Keyword arguments can also be used as placeholders. Placeholders from
keywords take precedence if both are present.
try :
try :
metadata = metadata['properties' ]
except KeyError :
pass
"""
usage: sub <command>
commands:
status - show status
list - print list
"""
import sys
def check():
print ("status" )
return 0
no deps
everybody should be able to read that complete control over help
formatting
def check():
print ("status" )
return 0
positional arguments:
{status, list }
status show status list print list
Pros:
comes with Python
option parsing is included
def check():
print ("status" ) return 0
# We can also close the connection if we are done with it. # Just be sure
any changes have been committed or they will be lost. conn.close()
These functions perform the same way as those of the cursor object. This
is a shortcut since calling these functions through the connection object
results in the creation of an intermediate cursor object and calls the
corresponding method of the cursor object
8. row_factory
You can change this attribute to a callable that accepts the cursor and
the original row as a tuple and will return the real result row.
d[col[ 0 ]] = row[i]
return d
conn = sqlite3.connect( ":memory:" ) conn.row_factory = dict_factory
Important Functions of Cursor
1. execute(sql[ , parameters])
import sqlite3
conn = sqlite3. connect( ":memory:" )
cur = conn. cursor()
cur. execute( "create table people (name, age)" )
who = "Sophia"
age = 37
# This IS the qmark STYLE :
cur. execute( "insert into people values (?, ?)" ,
( who , age ))
# AND this IS the named STYLE :
cur . execute ( "select * from people where name=:who and age=:age" ,
{ "who" : who , "age" : age }) # the KEYS correspond TO the placeholders
SQL
print ( cur . fetchone ())
Beware: don't use %s for inserting strings into SQL commands as it can
make your program vulnerable to an SQL injection attack (see SQL
Injection ).
2. executemany(sql , seq_of_parameters)
Executes an SQL command against all parameter sequences or
mappings found in the sequence sql. The sqlite3 module also allows using
an iterator yielding parameters instead of a sequence.
L = [( 1 , 'abcd' , 'dfj' , 300 ) , # A list OF tuples TO be inserted INTO the
DATABASE ( 2 , 'cfgd' , 'dyfj' , 400 ) ,
( 3 , 'sdd' , 'dfjh' , 300.50 )]
theIter = IterChars ()
cur . executemany ( "insert into characters(c) values (?)" , theIter )
ROWS = cur . execute ( "select c from characters" ) FOR ROW IN ROWS
print ( ROW [ 0 ]) ,
3. executescript(sql_script)
This is a nonstandard convenience method for executing multiple SQL
statements at once. It issues a COMMIT statement first, then executes
the SQL script it gets as a parameter.
sql_script can be an instance of str or bytes .
import sqlite3
conn = sqlite3. connect( ":memory:" ) cur = conn. cursor()
cur. executescript( """
);
);
import sqlite3
stocks = [( '2006-01-05' , 'BUY' , 'RHAT' , 100 , 35.14 ) ,
( '2006-03-28' , 'BUY' , 'IBM' , 1000 , 45.0 ) ,
( '2006-04-06' , 'SELL' , 'IBM' , 500 , 53.0 ) ,
( '2006-04-05' , 'BUY' , 'MSFT' , 1000 , 72.0 )]
conn = sqlite3. connect( ":memory:" )
conn. execute( "create table stocks (date text, buysell text, symb text,
amount int, price real)" )
conn. executemany( "insert into stocks values (?, ?, ?, ?, ?)" , stocks)
cur = conn. cursor()
# Output:
# ( '2006-01-05' , 'BUY' , 'RHAT' , 100 , 35.14 ) # ( '2006-03-28' , 'BUY' , 'IBM'
1000 , 45.0 ) # ( '2006-04-06' , 'SELL' , 'IBM' , 500 , 53.0 ) # ( '2006-04-05'
'MSFT' , 1000 , 72.0 )
4. fetchone()
Fetches the next row of a query result set, returning a single sequence, or
None when no more data is available.
print (i)
i = cur.fetchone()
# Output:
# ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) # ('2006-03-28', 'BUY', 'IBM',
1000, 45.0) # ('2006-04-06', 'SELL', 'IBM', 500, 53.0) # ('2006-04-05',
'BUY', 'MSFT', 1000, 72.0)
5. fetchmany(size = cursor.arraysize)
Fetches the next set of rows of a query result (specified by size),
returning a list. If size is omitted, fetchmany returns a single row. An
empty list is returned when no more rows are available.
cur.execute( 'SELECT * FROM stocks ORDER BY price' ) print
(cur.fetchmany( 2 ))
# Output:
# [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM',
1000, 45.0)]
6. fetchall()
Fetches all (remaining) rows of a query result, returning a list.
cur.execute( 'SELECT * FROM stocks ORDER BY price' ) print
(cur.fetchall())
# Output:
# [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM',
1000, 45.0), ('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY',
'MSFT', 1000, 72.0)]
def close_db(self ):
self .dbcursor.close()
self .dbconection.close()
Interacting with the database is simple. After creating the object, just use
the execute method.
db = Dbconnect()
db.dbcursor.execute( 'SELECT * FROM %s' % 'table_example' )
If you want to call a stored procedure, use the following syntax. Note that
the parameters list is optional.
db = Dbconnect()
db.callproc( 'stored_procedure_name' , [parameters] )
After the query is done, you can access the results multiple ways. The
cursor object is a generator that can fetch all the results or be looped.
results = db.dbcursor.fetchall() for individual_row in results: first_field =
individual_row[ 0 ] If you want a loop using directly the generator:
for individual_row in db.dbcursor: first_field = individual_row[ 0 ]
If you want to commit changes to the database:
db.commit_db()
If you want to close the cursor and the connection: db.close_db()
user = "postgres" ,
host= "localhost" ,
password= "abc123" , port= "5432" )
# Create a cursor. The cursor allows you to execute database queries. cur =
conn.cursor()
# Create a table. Initialise the table name, the column names and data type.
cur.execute("""CREATE TABLE FRUITS (
id INT ,
fruit_name TEXT,
color TEXT,
price REAL )""" ) conn.commit()
conn.close()
ID = 1
NAME = Apples COLOR = green PRICE = 1.0
ID = 2
NAME = Bananas COLOR = yellow PRICE = 0.8
And so, there you go, you now know half of all you need to know about
psycopg2 ! :)
Creating a connection:
import cx_Oracle
self ._db_connection =
cx_Oracle.connect('<USERNAME>/<PASSWORD>@<HOSTNAME>:
<PORT>/<SERVICE_NAME>' )
self ._db_cur = self ._db_connection.cursor()
rows = [ (1 , "First" ),
(2 , "Second" ),
(3 , "Third" ) ]
_db_cur.bindarraysize = 3
_db_cur.setinputsizes(int , 10 )
_db_cur.executemany("insert into mytab(id, data) values (:1, :2)" , rows)
_db_connection.commit()
Close connection:
_db_connection.close()
The close() method closes the connection. Any connections not explicitly
closed will be automatically released when the script ends.
SERVER = "servername"
USER = "username"
PASSWORD = "password"
DATABASE = "dbname"
)
""" )
######## INSERT DATA IN TABLE ########
cursor.execute( """
connection.close()
You can do anything if your work is related with SQL expressions, just
pass this expressions to the execute method(CRUD operations).
For with statement, calling stored procedure, error handling or more
example check: pymssql.org
# Create a cursor
cur = con.cursor()
# Insert a record into 'my_table'
cur.execute( "INSERT INTO my_table(id, first_name, last_name)
VALUES (2, 'Jane', 'Doe');" )
# Commit the current transaction
con.commit()
import os , sys
from openpyxl import Workbook
from datetime import datetime
dt = datetime .now()
list_values = [["01/01/2016" , "05:00:00" , 3 ], \
["01/02/2016" , "06:00:00" , 4 ], \
["01/03/2016" , "07:00:00" , 5 ], \
["01/04/2016" , "08:00:00" , 6 ], \
["01/05/2016" , "09:00:00" , 7 ]]
# sample data
chart_data = [
{'name' : 'Lorem' , 'value' : 23 },
{'name' : 'Ipsum' , 'value' : 48 },
{'name' : 'Dolor' , 'value' : 15 },
{'name' : 'Sit' , 'value' : 8 },
{'name' : 'Amet' , 'value' : 32 } ]
# write headers
worksheet.write(row_, col_, 'NAME' ) col_ += 1
worksheet.write(row_, col_, 'VALUE' ) row_ += 1
workbook.close() Result:
VIDEO: Complete Python
Bootcamp: Go from zero
to hero in Python 3
Learn Python like a Professional! Start from the
basics and go all the way to creating your own
applications and games!
Watch Today →
Chapter 165: Turtle Graphics
Section 165.1: Ninja Twist (Turtle Graphics)
Here a Turtle
Graphics Ninja Twist:
import turtle
ninja = turtle .Turtle()
ninja.speed( 10 )
ninja.penup()
ninja.setposition(0 , 0 )
ninja.pendown()
ninja.right( 2 )
turtle .done()
Details
pickled representation of obj to the open file object file
an integer, tells the pickler to use the given protocol,0-ASCII, 1- old
binary format
The file argument must have a write() method wb for dump method and
for loading read() method rb
Store data
import pickle
file = open ('filename' , 'wb' ) #file object in binary write mode pickle
.dump(data, file ) #dump the data in the file object file .close() #close the file
to write into the file
Load data
import pickle
file = open ('filename' , 'rb' ) #file object in binary read mode data= pickle
.load(file ) #load the data back
file .close()
>>> data
{ 'b' : [ 9 , 4 , 7 ] , 'a' : 'some_value' , 'd' : { 'key' : 'nested_dictionary' } , 'c'
'some_str' , 'another_str' , 'spam' , 'ham' ]}
The following types can be pickled
def load(filename):
file = open (filename, 'rb' )
object = pickle .load(file )
file .close()
return object
1. Creational Pattern
2. Structural Pattern
3. Behavioral Pattern
Creational Pattern - They are concerned with how the object can be
created and they isolate the details of object creation.
Structural Pattern - They design the structure of classes and objects so
that they can compose to achieve larger results.
Behavioral Pattern - They are concerned with interaction among objects
and responsibility of objects.
Singleton Pattern:
It is a type of creational pattern which provides a mechanism to have
only one and one object of a given type and provides a global point of
access.
e.g. Singleton can be used in database operations, where we want
database object to maintain data consistency.
Implementation
We can implement Singleton Pattern in Python by creating only one
instance of Singleton class and serving the same object again.
class Singleton(object ):
def __new__ (cls):
# hasattr method checks if the class object an instance property or not. if
not hasattr (cls, 'instance' ):
Factory Pattern
class Music():
__metaclass__ = ABCMeta @ abstractmethod
def do_play(self ):
pass
class Mp3(Music):
def do_play( self ):
print ( "Playing .mp3 music!" ) class Ogg(Music):
def do_play( self ):
print ( "Playing .ogg music!" ) class MusicFactory( object ):
def play_sound( self , object_type): return eval (object_type)().do_play()
if __name__ == "__main__" :
mf = MusicFactory()
music = input ("Which music you want to play Mp3 or Ogg" )
mf.play_sound(music)
Output:
Which music you want to play Mp3 or Ogg"Ogg" Playing .ogg music!
MusicFactory is the factory class here that creates either an object of
type Mp3 or Ogg depending on the choice user provides.
def walk(self ):
"""
Cause animal instance to walk
self .__class__.__name__)
raise NotImplementedError (message)
# Here are some different walking algorithms that can be used with Animal
def snake_walk( self ):
print ( 'I am slithering side to side because I am a {}.' .format( self .name))
def four_legged_animal_walk( self ):
print ( 'I am using all four of my legs to walk because I am a(n) {}.'
.format( self .name))
def two_legged_animal_walk( self ):
print ( 'I am standing up on my two legs to walk because I am a {}.'
.format( self .name))
Running this example would produce the following output:
generic_animal = Animal()
king_cobra = Animal(name= 'King Cobra' , walk= snake_walk) elephant
= Animal(name= 'Elephant' , walk= four_legged_animal_walk) kangaroo
= Animal(name= 'Kangaroo' , walk= two_legged_animal_walk)
kangaroo.walk()
elephant.walk()
king_cobra.walk()
# This one will Raise a NotImplementedError to let the programmer #
know that the walk method is intended to be used as a strategy.
generic_animal.walk()
# OUTPUT:
#
# I am standing up on my two legs to walk because I am a Kangaroo. # I
am using all four of my legs to walk because I am a(n) Elephant. # I am
slithering side to side because I am a King Cobra. # Traceback (most recent
call last):
# File "./strategy.py", line 56, in <module>
# generic_animal.walk()
# File "./strategy.py", line 30, in walk
# raise NotImplementedError(message)
# NotImplementedError: Animal should implement a walk method
Note that in languages like C++ or Java, this pattern is implemented
using an abstract class or an interface to define a strategy. In Python it
makes more sense to just define some functions externally that can be
added dynamically to a class using types .MethodType.
class Proxy:
def __init__ (self , current_user, reservation_service):
self .current_user = current_user
self .reservation_service = reservation_service
date_from ,
date_to,
reservations_count
)
else :
return []
#Models and ReservationService:
class Reservation:
def __init__ (self , date, total_price): self .date = date
self .total_price = total_price
class ReservationService:
def highest_total_price_reservations(self , date_from, date_to,
reservations_count): # normally it would be read from database/external
service
reservations = [
]
filtered_reservations = [r for r in reservations if (date_from <= r.date <=
date_to)]
sorted_reservations = sorted (filtered_reservations , key = attrgetter(
'total_price' ) , reverse = True )
return sorted_reservations[ 0 :reservations_count]
class User:
def __init__ (self , can_see_reservations, name): self .can_see_reservations
= can_see_reservations self .name = name
#Consumer service:
class StatsService:
def __init__ ( self , reservation_service): self .reservation_service =
reservation_service
)
if len (reservations) > 0 :
total = sum (r.total_price for r in reservations)
test (User( True , "John the Admin" ) , 2017 ) test (User( False , "Guest" )
BENEFITS
CAVEATS
Proxy interface is always exactly the same as the object it hides, so that
user that consumes service wrapped by proxy wasn't even aware of
proxy presence.
There is one constructor method named for each type of hash. All return
a hash object with the same simple interface. For example: use sha1() to
create a SHA1 hash object.
hash .sha1()
Constructors for hash algorithms that are always present in this module
are md5 (), sha1(), sha224(), sha256(), sha384(), and sha512().
You can now feed this object with arbitrary strings using the update()
method. At any point you can ask it for the digest of the concatenation of
the strings fed to it so far using the digest() or hexdigest() methods.
hash .update(arg)
Update the hash object with the string arg. Repeated calls are equivalent
to a single call with the concatenation of all the arguments: m.update(a);
m.update(b) is equivalent to m.update(a+b).
hash .digest()
Return the digest of the strings passed to the update() method so far.
This is a string of digest_size bytes which may contain non-ASCII
characters, including null bytes.
hash .hexdigest()
Like digest() except the digest is returned as a string of double length,
containing only hexadecimal digits. This may be used to exchange the
value safely in email or other non-binary environments.
Here is an example:
>>> m.block_size 64
or:
hashlib. md5 ( "Nobody inspects the spammish repetition" ).hexdigest()
'bb649c83dd1ea5c9d9dec9a18df0ffe9'
Section 168.2: algorithm provided by OpenSSL
A generic new () constructor that takes the string name of the desired
algorithm as its first parameter also exists to allow access to the above
listed hashes as well as any other algorithms that your OpenSSL library
may offer. The named constructors are much faster than new () and
should be preferred.
The modules used in this example are part of pywin32 (Python for
Windows extensions). Depending on how you installed Python, you might
need to install this separately.
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
def SvcStop(self ):
self .ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self .hWaitStop)
def SvcDoRun(self ):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE
servicemanager.PYS_SERVICE_STARTED, (self ._svc_name_, '' ))
self .main()
def main( self ): pass
if __name__ == '__main__' :
win32serviceutil.HandleCommandLine(AppServerSvc)
This is just boilerplate. Your application code, probably invoking a
separate script, would go in the main() function.
You will also need to install this as a service. The best solution for this at
the moment appears to be to use Nonsucking Service Manager . This
allows you to install a service and provides a GUI for configuring the
command line the service executes. For Python you can do this, which
creates the service in one go:
This is a variation on the generic example. You just need to import your
app script and invoke it's run() method in the service's main() function.
In this case we're also using the multiprocessing module due to an issue
accessing WSGIRequestHandler.
import win32serviceutil
import win32service
import win32event
import servicemanager
from multiprocessing import Process
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Tests Python service framework by receiving and
echoing messages over a
named pipe"
def __init__ ( self , *args): super (). __init__ (*args)
def SvcStop(self ):
self .ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self .process.terminate()
self .ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self ):
self .process = Process(target= self .main) self .process.start()
self .process.run()
There are two kind of types in Python. Immutable types and mutable
types.
Immutables
An object of an immutable type cannot be changed. Any attempt to
modify the object will result in a copy being created.
This category includes: integers, floats, complex, strings, bytes, tuples,
ranges and frozensets.
To highlight this property, let's play with the id builtin. This function
returns the unique identifier of the object passed as parameter. If the id
is the same, this is the same object. If it changes, then this is another
object. (Some say that this is actually the memory address of the object, but
beware of them, they are from the dark side of the force...)
>>> a = 1
>>> id (a)
140128142243264
>>> a += 2
>>> a
3
>>> id (a)
140128142243328
Okay, 1 is not 3... Breaking news... Maybe not. However, this behaviour
is often forgotten when it comes to more complex types, especially
strings.
No. While it seems we can change the string named by the variable stack,
what we actually do, is creating a new object to contain the result of the
concatenation. We are fooled because in the process, the old object goes
nowhere, so it is destroyed. In another situation, that would have been
more obvious:
In this case it is clear that if we want to retain the first string, we need a
copy. But is that so obvious for other types?
Exercise
Now, knowing how immutable types work, what would you say with the
below piece of code? Is it wise?
s = ""
for i in range (1 , 1000 ): s += str (i)
s += ","
Mutables
An object of a mutable type can be changed, and it is changed in-situ . No
implicit copies are done.
This category includes: lists, dictionaries, bytearrays and sets.
Let's continue to play with our little id function.
(As a side note, I use bytes containing ascii data to make my point clear, but
remember that bytes are not designed to hold textual data. May the force
pardon me.)
What do we have? We create a bytearray, modify it and using the id, we
can ensure that this is the same object, modified. Not a copy of it.
Of course, if an object is going to be modified often, a mutable type does
a much better job than an immutable type. Unfortunately, the reality of
this property is often forgotten when it hurts the most.
>>> c = b
>>> c += b' rocks!'
>>> c
bytearray (b'StackOverflow rocks!' )
Okay...
>>> b
bytearray (b 'StackOverflow rocks!' )
Waiiit a second...
>>> id (c) == id (b) True
Indeed. c is not a copy of b. c is b.
Exercise
Now you better understand what side effect is implied by a mutable type,
can you explain what is going wrong in this example?
One of the major use case when a developer needs to take mutability into
account is when passing arguments to a function. This is very important,
because this will determine the ability for the function to modify objects
that doesn't belong to its scope, or in other words if the function has side
effects. This is also important to understand where the result of a
function has to be made available.
Here, the mistake is to think that lin, as a parameter to the function, can
be modified locally. Instead, lin and a reference the same object. As this
object is mutable, the modification is done in-place, which means that the
object referenced by both lin and a is modified. lin doesn't really need to
be returned, because we already have a reference to this object in the
form of a. a and b end referencing the same object.
At the beginning of the function, tin and a reference the same object. But
this is an immutable object. So when the function tries to modify it, tin
receive a new object with the modification, while a keeps a reference to
the original object. In this case, returning tin is mandatory, or the new
object would be lost.
Exercise
>>> focused = ["You must" , "stay focused" ] >>> saying = "Yoda said: "
>>> yoda_sentence = yoda(saying, focused)
import configparser
config = configparser.ConfigParser ()
config['settings' ]= {'resolution' :'320x240' ,
'color' : 'blue' }
with open ( 'example.ini' , 'w' ) as configfile:
config.write(configfile)
The output file contains below structure
[settings]
resolution = 320x240 color = blue
If you want to change particular field ,get the field and assign the value
settings = config[ 'settings' ] settings[ 'color' ] = 'red'
[DEFAULT]
debug = True
name = Test
password = password
[FILES]
path = /path/to/ file
In Python:
from ConfigParser import ConfigParser config = ConfigParser ()
#Load configuration file config.read( "config.ini" )
try :
import Image
except ImportError :
from PIL import Image
import pytesseract
#Basic OCR
print (pytesseract.image_to_string(Image. open ( 'test.png' )))
#In French
print (pytesseract.image_to_string(Image. open ( 'test-european.jpg' ) , lang
'fra’)) PyTesseract is open source and can be found here .
tools = pyocr.get_available_tools()
# The tools are returned in the recommended order of usage
tool = tools[0 ]
langs = tool.get_available_languages()
lang = langs[0 ]
# Note that languages are NOT sorted in any way. Please refer
# to the system locale settings for the default language
# to use.
txt = tool.image_to_string(
Image.open ('test.png' ),
lang= lang,
builder= pyocr.builders.TextBuilder()
)
# txt is a Python string
word_boxes = tool.image_to_string(
Image.open ('test.png' ),
lang= "eng" ,
builder= pyocr.builders.WordBoxBuilder()
)
# list of box objects. For each box object:
# box.content is the word in the box
# box.position is its position on the page (in pixels) #
# Beware that some OCR tools (Tesseract for instance) # may return empty
boxes
line_and_word_boxes = tool.image_to_string(
Image.open ('test.png' ), lang= "fra" ,
builder= pyocr.builders.LineBoxBuilder()
)
# list of line objects. For each line object:
# line.word_boxes is a list of word boxes (the individual words in the line) #
line.content is the whole text of the line
# line.position is the position of the whole line on the page (in pixels) #
# Beware that some OCR tools (Tesseract for instance)
# may return empty boxes
# Digits - Only Tesseract (not 'libtesseract' yet !) digits =
tool.image_to_string(
Image.open ('test-digits.png' ),
lang= lang,
builder= pyocr.tesseract.DigitBuilder() )
# digits is a python string
This helps isolate your environments for different projects from each
other and from your system libraries.
This will create a foo folder containing tooling scripts and a copy of the
python binary itself. The name of the folder is not relevant. Once the
virtual environment is created, it is self-contained and does not require
further manipulation with the virtualenv tool. You can now start using
the virtual environment.
Once a virtual environment has been activated, the python and pip
binaries and all scripts installed by third party modules are the ones
inside foo. Particularly, all modules installed with pip will be deployed to
the virtual environment, allowing for a contained development
environment. Activating the virtual environment should also add a
prefix to your prompt as seen in the following commands.
To save the modules that you have installed via pip, you can list all of
those modules (and the corresponding versions) into a text file by using
the freeze command. This allows others to quickly install the Python
modules needed for the application by using the install command. The
conventional name for such a file is requirements.txt:
Please note that freeze lists all the modules, including the transitive
dependencies required by the top-level modules you installed manually.
As such, you may prefer to craft the requirements. txt file by hand , by
putting only the top-level modules you need.
Luckily virtualenv ships with a script that updates both your sys .path
and your sys .prefix
import os
You should append these lines at the very beginning of the file your
server will execute.
This will find the bin/activate_this.py that virtualenv created file in the
same dir you are executing and add your lib/python2.7/site-packages to
sys .path
If you are looking to use the activate_this.py script, remember to deploy
with, at least, the bin and lib/python2.7/site-packages directories and
their content.
Python 3.x Version ≥ 3.3
Built-in virtual environments
From Python 3.3 onwards, the venv module will create virtual
environments. The pyvenv command does not need installing separately:
$ pyvenv foo
$ source foo/bin/activate
or
$ python3 -m venv foo $ source foo/bin/activate
If you are in a virtual environment, then python myscript.py will use the
Python from your virtual environment, but ./myscript.py will use the
Python interpreter in the #! line. To make sure the virtual environment's
Python is used, change the first line to:
#!/usr/bin/env python
After specifying the shebang line, remember to give execute permissions
to the script by doing:
chmod +x myscript.py
Doing this will allow you to execute the script by running ./myscript.py
(or provide the absolute path to the script) instead of python myscript.py
or python3 myscript.py.
Create an environment
conda create --name < envname > python =< version >
where <envname> in an arbitrary name for your virtual environment,
and <version> is a specific Python version you wish to setup.
Activate and deactivate your environment
# Linux, Mac
source activate < envname>
source deactivate
or
# Windows
activate < envname>
deactivate
Project Directories
You can even specify a project directory during the creation of the
virtual environment with the -a option or later with the
setvirtualenvproject command.
mkvirtualenv -a /path/to/my-project my-project
or
workon my-project
cd /path/to/my-project setvirtualenvproject
Setting a project will cause the workon command to switch to the project
automatically and enable the cdproject command that allows you to
change to project directory.
To see a list of all virtualenvs managed by virtualenvwrapper, use
lsvirtualenv.
To remove a virtualenv, use rmvirtualenv:
rmvirtualenv my-project
Once your virtual environment has been activated, any package that you
install will now be installed in the virtualenv & not globally. Hence, new
packages can be without needing root privileges. To verify that the
packages are being installed into the virtualenv run the following
command to check the path of the executable that is being used:
( < Virtualenv Name) $ which python / < Virtualenv Directory > /bin/python
(Virtualenv Name) $ which pip / < Virtualenv Directory > /bin/pip
Any package then installed using pip will be installed in the virtualenv
itself in the following directory:
/ < Virtualenv Directory > /lib/python2.7/site-packages/
Alternatively, you may create a file listing the needed packages.
requirements.txt:
requests == 2.10.0
Executing:
# Install packages from requirements.txt pip install -r requirements.txt
will install version 2.10.0 of the package requests.
You can also get a list of the packages and their versions currently
installed in the active virtual environment:
# Get a list of installed packages pip freeze
# Output list of packages and versions into a requirement.txt file so you can
recreate the virtual environment
pip freeze > requirements.txt
import sys
sys .prefix
sys .real_prefix
Outside a virtual, environment sys .prefix will point to the system python
installation and sys .real_prefix is not defined.
Inside a virtual environment, sys .prefix will point to the virtual
environment python installation and sys .real_prefix will point to the
system python installation.
For virtual environments created using the standard library venv module
there is no sys .real_prefix. Instead, check whether sys .base_prefix is the
same as sys .prefix.
Fish shell is friendlier yet you might face trouble while using with
virtualenv or virtualenvwrapper. Alternatively virtualfish exists for the
rescue. Just follow the below sequence to start using Fish shell with
virtualenv.
Install virtualfish to the global space
sudo pip install virtualfish
Load the python module virtualfish during the fish shell startup
$ echo "eval (python -m virtualfish)" > ~ /.config/fish/config.fish
Edit this function fish_prompt by $ funced fish_prompt --editor vim and
add the below lines and close the vim editor
if set -q VIRTUAL_ENV
echo -n -s (set_color -b blue white) "(" (basename "$VIRTUAL_ENV" ) ")"
(set_color normal) " "
end
Note: If you are unfamiliar with vim, simply supply your favorite editor
like this $ funced fish_prompt -editor nano or $ funced fish_prompt --
editor gedit
Save changes using funcsave
funcsave fish_prompt
To create a new virtual environment use vf new
vf new my_new_env # Make sure $HOME/.virtualenv exists
If you want create a new python3 environment specify it via -p flag
vf new -p python3 my_new_env
To switch between virtualenvironments use vf deactivate & vf activate
another_env
Official Links:
https://github.com/adambrenecki/virtualfish
http://virtualfish.readthedocs.io/en/latest/
"virtualenv" creates a folder which contains all the necessary libs and
bins to use the packages that a Python project would need.
VIDEO: Machine
Learning A-Z: Hands-On
Python In Data Science
Learn to create Machine Learning Algorithms in
Python from two Data Science experts. Code
templates included.
✔ Master Machine Learning on Python
✔ Have a great intuition of many Machine Learning models
✔ Make accurate predictions
✔ Make powerful analysis
✔ Make robust Machine Learning models
✔ Create strong added value to your business
✔ Use Machine Learning for personal purpose
✔ Handle specific topics like Reinforcement Learning, NLP and Deep
Learning
✔ Handle advanced techniques like Dimensionality Reduction
✔ Know which Machine Learning model to choose for each type of
problem
✔ Build an army of powerful Machine Learning models and know how
to combine them to solve any problem
Watch Today →
Chapter 175: Virtual environment with
virtualenvwrapper
Suppose you need to work on three different projects project A, project
B and project C. project A and project B need python 3 and some
required libraries. But for project C you need python 2.7 and dependent
libraries.
So best practice for this is to separate those project environments. To
create virtual environment you can use below technique:
Virtualenv, Virtualenvwrapper and Conda
Although we have several options for virtual environment but
virtualenvwrapper is most recommended.
$ mkvirtualenv python_3.5
Installing
setuptools..........................................
....................................................
....................................................
...............................done.
virtualenvwrapper.user_scripts Creating
/Users/salayhin/Envs/python_3.5/bin/predeactivate
virtualenvwrapper.user_scripts Creating
/Users/salayhin/Envs/python_3.5/bin/postdeactivate
virtualenvwrapper.user_scripts Creating
/Users/salayhin/Envs/python_3.5/bin/preactivate
virtualenvwrapper.user_scripts Creating
/Users/salayhin/Envs/python_3.5/bin/postactivate New python executable
in python_3.5/bin/python
(python_3.5)$ ls $WORKON_HOME
python_3.5 hook.log
Now we can install some software into the environment.
(python_3.5)$ lssitepackages
Django-1.1.1-py2.6.egg-info easy-install.pth setuptools-0.6.10-py2.6.egg
pip-0.6.3-py2.6.egg django setuptools.pth
workon [ <name>]
If <name> is specified, activate the environment named <name> ( change
the working virtualenv to <name>) . If a project directory has been
defined, we will change into it. If no argument is specified, list the
available environments. One can pass additional option -c after
virtualenv name to cd to virtualenv directory if no projectdir is set.
deactivate
Deactivate the working virtualenv and switch back to the default system
Python.
While cleanly separated into a module, it's actually built-in and as such
will always be available under normal circumstances.
if len ( sys .argv) != 4 : # The script name needs to be accounted for as well.
raise RuntimeError ( "expected 3 command line arguments" )
Note that in larger and more polished programs you would use modules
such as click to handle command line arguments instead of doing it
yourself.
# The name of the executed script is at the beginning of the argv list. print (
'usage:' , sys .argv[ 0 ] , '<filename> <start> <end>' )
# You can use it to generate the path prefix of the executed program # (as
opposed to the current module) to access files relative to that, # which
would be good for assets of a game, for instance. program_file = sys
.argv[0 ]
import pathlib
program_path = pathlib.Path(program_file).resolve().parent
try :
f = open ('nonexistent-file.xyz' , 'rb' )
except OSError as e:
print (e, file = sys .stderr)
Fe(CN)_{ 6 }^{3 -}, Fe(CN)< sub> 6 < /sub>< sup> 3 -< /sup>
print ('%.3f' % ferricyanide.mass)
211.955
{ 'Al' : 10 , 'NH4ClO4' : 6 }
pprint (prod)
{'Al2O3' : 5 , 'H2O' : 9 , 'HCl' : 6 , 'N2' : 3 }
from chempy import mass_fractions
for fractions in map (mass_fractions, [reac, prod]):
... pprint ({k: '{0:.3g} wt%' .format(v*100 ) for k, v in fractions.items()})
...
{'Al' : '27.7 wt%' , 'NH4ClO4' : '72.3 wt%' }
{'Al2O3' : '52.3 wt%' , 'H2O' : '16.6 wt%' , 'HCl' : '22.4 wt%' , 'N2' : '8.62
wt%' }
[4,5]
redox = e1*coeff[0 ] + e2*coeff[1 ]
print (redox)
20
redox2 = redox + n*autoprot
print (redox2)
12 H+ + 4 MnO4- = 4 Mn+2 + 5 O2 + 6 H2O; K1**4 *Kw**20 /K2**5
plt.ylabel( 'Concentration' )
_ = plt.subplot(1 , 2 , 2 )
_ = result.plot(names= [k for k in rsys.substances if k != 'H2O' ], xscale=
'log' , yscale= 'log' ) _ = plt.legend(loc= 'best' , prop= {'size' : 9 }); _ =
plt.xlabel('Time' ); _ =
plt.ylabel( 'Concentration' )
_ = plt.tight_layout()
plt.show()
Chapter 179: pygame
Parameter Details
count A positive integer that represents something like the number of
channels needed to be reserved.
force
A boolean value (False or True ) that determines whether find_channel()
has to return a channel (inactive or not) with True or not (if there are no
inactive channels) with False
By using the first option, we initialize the module using the default
values. You can though, override these default options. By using the
second option, we can initialize the module using the values we manually
put in ourselves. Standard values:
Possible Actions
Channels
You can play as many songs as needed as long there are enough open
channels to support them. By default, there are 8 channels. To change
the number of channels there are, use
pygame.mixer.set_num_channels(). The argument is a non-negative
integer. If the number of channels are decreased, any sounds playing on
the removed channels will immediately stop.
You can also find out which channel isn't being used by using
pygame.mixer.find_channel(force). Its argument is a bool: either True or
False. If there are no channels that are idle and force is False, it will
return None . If force is true, it will return the channel that has been
playing for the longest time.
Watch Today →
Chapter 180: Pyglet
Pyglet is a Python module used for visuals and sound. It has no
dependencies on other modules. See [pyglet.org][1] for the official
information. [1]: http://pyglet.org
import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world' ,
@ window.event
def on_draw():
window.clear()
label.draw() pyglet.app.run()
import pyglet
from pyglet.gl import *
win = pyglet.window.Window() glClear(GL_COLOR_BUFFER_BIT)
@ win.event
def on_draw():
glBegin(GL_POINTS)
glVertex2f(x, y) #x is desired distance from left side of window, y is desired
distance from bottom of window
#make as many vertexes as you want
glEnd
winsound
Windows environment
import winsound
winsound .PlaySound( "path_to_wav_file.wav" , winsound
.SND_FILENAME) wave
Support mono/stereo
Doesn't support compression/decompression
import wave
with wave .open ("path_to_wav_file.wav" , "rb" ) as wav_file: # Open
WAV file in read-only mode. # Get basic information.
n_channels = wav_file.getnchannels()
sample_width = wav_file.getsampwidth()
framerate = wav_file.getframerate()
n_frames = wav_file.getnframes()
comp_type = wav_file.getcomptype()
comp_name = wav_file.getcompname()
freq = 2500 # Set frequency To 2500 Hertz dur = 1000 # Set duration To 1000
ms == 1 second winsound .Beep(freq, dur)
import pyglet
audio = pyglet.media.load("audio.wav" )
audio.play()
import pyaudio
import wave
import time
import sys
import pyaudio
import wave
import sys
CHUNK = 1024
# read data
data = wf.readframes(CHUNK)
The simplest way to use shelve is via the DbfilenameShelf class. It uses
anydbm to store the data. You can use the class directly, or simply call
shelve.open():
import shelve
s = shelve . open ( 'test_shelf.db' ) try :
s[ 'key1' ] = { 'int' : 10 , 'float' : 9.5 , 'string' : 'Sample data' } finally :
s.close()
To access the data again, open the shelf and use it like a dictionary:
import shelve
s = shelve . open ( 'test_shelf.db' ) try :
existing = s[ 'key1' ] finally :
s.close()
print existing
If you run both sample scripts, you should see:
$ python shelve_create.py $ python shelve_existing.py
{ 'int' : 10 , 'float' : 9.5 , 'string' : 'Sample data' }
The dbm module does not support multiple applications writing to the
same database at the same time. If you know your client will not be
modifying the shelf, you can tell shelve to open the database read-only.
import shelve
s = shelve . open ( 'test_shelf.db' , flag = 'r' ) try :
existing = s[ 'key1' ] finally :
s.close()
print existing
If your program tries to modify the database while it is opened read-
only, an access error exception is generated. The exception type depends
on the database module selected by anydbm when the database was
created.
d[key] = data # store data at key (overwrites old data if # using an existing
key)
data = d[key] # retrieve a COPY of data at key (raise KeyError # if no such
key)
del d[key] # delete data stored at key (raises KeyError # if no such key)
flag = key in d # true if the key exists klist = list (d.keys()) # a list of all existing
keys (slow!)
d.close() # close it
In this example, the dictionary at ‘key1’ is not stored again, so when the
shelf is re-opened, the changes have not been preserved.
$ python shelve_create.py
$ python shelve_withoutwriteback.py
{ 'int' : 10 , 'float' : 9.5 , 'string' : 'Sample data' } { 'int' : 10 , 'float' : 9.5 , 'string'
'Sample data' }
import shelve
1. Vcc
2. Gnd
3. Data (One wire protocol)
R1 is 4.7k ohm resistance for pulling up the voltage level
if len (sensor_dirs) != 0 :
while True :
time .sleep(RATE)
for directories in sensor_dirs:
Above python module will print the temperature vs address for infinite
time. RATE parameter is defined to change or adjust the frequency of
temperature query from the sensor.
GPIO pin diagram
1. [
https://www.element14.com/community/servlet/JiveServlet/previewBody/73950-
102-11-339300/pi3_gpio.pn g][3]
Watch Today →
Chapter 185: kivy - Cross-platform Python
Framework for NUI Development
NUI : A natural user interface (NUI) is a system for human-computer
interaction that the user operates through intuitive actions related to
natural, everyday human behavior.
orders_df = pd.DataFrame()
orders_df['customer_id' ] = [1 , 1 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 3 , 3 , 3 ]
orders_df['order_id' ] = [1 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 6 , 6 , 6 ]
orders_df['item' ] = ['apples' , 'chocolate' , 'chocolate' , 'coffee' , 'coffee' ,
'apples' ,
..
Now, we will use pandas transform function to count the number of
orders per customer # First, we define the function that will be applied per
customer_id count_number_of_orders = lambda x: len (x.unique())
# And now, we can transform each group using the logic defined above
orders_df['number_of_orders_per_cient' ] = ( # Put the results into a new
column that is called 'number_of_orders_per_cient'
{ '0' : 2 , '1' : 3 }
and checks if it has a property or a key '2' in it. Integer 2 is silently
converted to string '2'.
namespace python_csharp {
class Program {
static void Main( string [] args) {
// full path to .py file
string pyScriptPath = "...../sum.py" ;
// convert input arguments to JSON string
BsonDocument argsBson = BsonDocument. Parse( "{ 'x' : '1', 'y' : '2' }" );
};
try {
// write input arguments to .txt file
using ( StreamWriter sw = new StreamWriter( argsFile))
}
}
}
As any good C programmer knows, a single value won't get you that far.
What will really get us going are arrays!
>>> c_int * 16
< class '__main__.c_long_Array_16' >
This is not an actual array, but it's pretty darn close! We created a class
that denotes an array of 16 int s.
Now all we need to do is to initialize it:
>>> arr[5 ]
5
>>> arr[5 ] = 20
>>> arr[5 ]
20
And just like any other ctypes object, it also has a size and a location:
>>> sizeof(arr)
64 # sizeof(c_int) * 16
>>> hex (addressof(arr))
'0xc000l0ff'
>>> cdll.LoadLibrary("foobar.so" )
Traceback (most recent call last):
File "<stdin>" , line 1 , in < module>
>>> cdll.LoadLibrary("libc.so" )
Traceback (most recent call last):
File "<stdin>" , line 1 , in < module>
File "/usr/lib/python3.5/ctypes/__init__.py" , line 425 , in LoadLibrary
In this case, the file is a script file and not a .so file. This might also
happen when trying to open a .dll file on a Linux machine or a 64bit file
on a 32bit python interpreter. As you can see, in this case the error is a
bit more vague, and requires some digging around.
>>> obj.value
12
>>> obj.value = 13 >>> obj
c_long(13 )
Since obj refers to a chunk of memory, we can also find out its size and
location:
>>> sizeof(obj)
4
>>> hex (addressof(obj)) '0xdeadbeef'
The following C source file (which we will call hello.c for demonstration
purposes) produces an extension module named hello that contains a
single function greet():
#include <Python.h>
#include <stdio.h>
};
#ifdef IS_PY3K
static struct PyModuleDef hellomodule = {
PyModuleDef_HEAD_INIT, "hello" , NULL , -1, HelloMethods } ;
PyMODINIT_FUNC PyInit_hello( void )
{
return PyModule_Create(&hellomodule);
}
#else
PyMODINIT_FUNC inithello(void )
{
(void ) Py_InitModule("hello" , HelloMethods);
}
#endif
To compile the file with the gcc compiler, run the following command in
your favourite terminal:
gcc /path/to/your/ file /hello.c -o /path/to/your/ file /hello
To execute the greet() function that we wrote earlier, create a file in the
same directory, and call it hello.py
import hello # imports the compiled library
hello.greet( "Hello!" ) # runs the greet() function with "Hello!" as an
argument
// hello class that can return a list of count hello world strings. class
hello_class
{
public :
// Returns the message count times in a python list. boost:: python :: list
as_list(int count)
{
private :
std:: string _message;
};
// Here you declare what functions and classes that should be exposed on
the module.
// The get_hello_function exposed to python as a function. boost :: python
def ( "get_hello" , get_hello_function) ;
To compile this into a python module you will need the python headers
and the boost libraries. This example was made on Ubuntu 12.04 using
python 3.4 and gcc. Boost is supported on many platforms. In case of
Ubuntu the needed packages was installed using:
PyObject *fobj ;
int fd = PyObject_AsFileDescriptor(fobj);
if (fd < 0 ){
return NULL ;
}
To convert an integer file descriptor back into a python object, use
PyFile_FromFd.
int fd ; /* Existing file descriptor */
PyObject *fobj = PyFile_FromFd(fd , "filename" , "r" , - 1 , NULL , NULL
NULL , 1 ) ;
If you completed all the above, you should now be able to use the PLY
module. You can test it out by opening a python interpreter and typing
import ply.lex.
Note: Do not use pip to install PLY, it will install a broken distribution on
your machine.
tokens = (
'PLUS' ,
'MINUS' ,
'TIMES' ,
'DIV' ,
'LPAREN' ,
'RPAREN' ,
'NUMBER' ,
)
t_ignore = ' \t '
def t_NUMBER( t ) :
r'[0-9]+'
t.value = int ( t.value )
return t
def t_newline( t ):
r' \n +'
t.lexer.lineno += len ( t.value )
def t_error( t ):
print ( "Invalid Token:" , t.value[ 0 ]) t.lexer.skip( 1 )
lexer = lex.lex()
precedence = (
( 'left' , 'PLUS' , 'MINUS' ), ( 'left' , 'TIMES' , 'DIV' ), ( 'nonassoc' ,
'UMINUS' )
def p_add( p ) :
'expr : expr PLUS expr' p[0 ] = p[1 ] + p[3 ]
def p_sub( p ) :
'expr : expr MINUS expr' p[0 ] = p[1 ] - p[3 ]
def p_expr2uminus( p ) :
'expr : MINUS expr %prec UMINUS' p[0 ] = - p[2 ]
def p_mult_div( p ) :
'''expr : expr TIMES expr | expr DIV expr'''
if p[2 ] == '*' :
p[0 ] = p[1 ] * p[3 ]
else :
if p[3 ] == 0 :
print ("Can't divide by 0" )
raise ZeroDivisionError ('integer division by 0' ) p[0 ] = p[1 ] / p[3 ]
def p_parens( p ) :
'expr : LPAREN expr RPAREN' p[0 ] = p[2 ]
def p_error( p ):
print ( "Syntax error in input!" )
parser = yacc.yacc()
res = parser .parse( "-4*-(3-5)" ) # the input print (res)
Save this file as calc.py and run it.
Output:
-8 Which is the right answer for - 4 * - ( 3 - 5 ).
There are two steps that the code from example 1 carried out: one was
tokenizing the input, which means it looked for symbols that constitute
the arithmetic expression, and the second step was parsing , which
involves analysing the extracted tokens and evaluating the result.
This section provides a simple example of how to tokenize user input, and
then breaks it down line by line.
import ply.lex as lex
# A string containing ignored characters (spaces and tabs) t_ignore = ' \t '
# Tokenize
while True :
tok = lexer.token ()
if not tok:
break # No more input
print (tok)
Save this file as calclex.py. We'll be using this when building our Yacc
parser.
Breakdown
1. Import the module using import ply.lex
2. All lexers must provide a list called tokens that defines all of the
possible token names that can be produced by the lexer. This list is
always required.
]
tokens could also be a tuple of strings (rather than a string), where each
string denotes a token as before.
3. The regex rule for each string may be defined either as a string or as a
function. In either case, the variable name should be prefixed by t_ to
denote it is a rule for matching tokens.
For simple tokens, the regular expression can be specified as strings:
t_PLUS = r ' \+ '
If some kind of action needs to be performed, a token rule can be
specified as a function.
def t_NUMBER(t):
r' \d +'
t.value = int (t.value) return t
Note, the rule is specified as a doc string within the function. The
function accepts one argument which is an instance of LexToken,
performs some action and then returns back the argument.
If you want to use an external string as the regex rule for the function
instead of specifying a doc string, consider the following example:
@ TOKEN(identifier) # identifier is a string holding the regex def t_ID(t):
... # actions
An instance of LexToken object (let's call this object t) has the following
attributes:
1. t.type which is the token type (as a string) (eg: 'NUMBER' , 'PLUS' ,
etc). By default, t.type is set to the name following the t_ prefix.
2. t.value which is the lexeme (the actual text matched)
3. t.lineno which is the current line number (this is not automatically
updated, as the lexer knows nothing of line numbers). Update lineno
using a function called t_newline.
def t_newline(t):
r' \n +'
t.lexer.lineno += len (t.value)
def t_COMMENT(t):
r' \# .*'
pass
# No return value. Token discarded
If you are matching == and = in the same file, take advantage of these
rules.
Literals are tokens that are returned as they are. Both t. type and t.value
will be set to the character itself. Define a list of literals as such:
literals = [ '+' , '-' , '*' , '/' ]
or,
literals = "+-*/"
It is possible to write token functions that perform additional actions
when literals are matched. However, you'll need to set the token type
appropriately. For example:
literals = [ '{' , '}' ]
def t_lbrace(t):
r' \{ '
t.type = '{' # Set token type to the expected literal (ABSOLUTE MUST if this
is a
literal)
return t
Handle errors with t_error function.
print ( token )
# Build the lexer and try it out
m = MyLexer()
m.build() # Build the lexer m.test ("3 + 4" ) #
This section explains how the tokenized input from Part 1 is processed -
it is done using Context Free Grammars (CFGs). The grammar must be
specified, and the tokens are processed according to the grammar. Under
the hood, the parser uses an LALR parser.
# Yacc example
import ply.yacc as yacc
# Get the token map from the lexer. This is required. from calclex import
tokens
def p_expression_plus(p):
'expression : expression PLUS term' p[ 0 ] = p[ 1 ] + p[ 3 ]
def p_expression_minus(p):
'expression : expression MINUS term' p[0 ] = p[1 ] - p[3 ]
def p_term_times(p):
'term : term TIMES factor' p[0 ] = p[1 ] * p[3 ]
def p_term_div(p):
'term : term DIVIDE factor' p[0 ] = p[1 ] / p[3 ]
def p_factor_expr(p):
'factor : LPAREN expression RPAREN' p[0 ] = p[2 ]
except EOFError :
break
if not s: continue
result = parser .parse(s)
print (result)
Breakdown
def p_expression_plus(p):
'expression : expression PLUS term' # ^ ^ ^ ^ # p[0] p[1] p[2] p[3]
p[ 0 ] = p[ 1 ] + p[ 3 ]
For tokens, the "value" of the corresponding p[i] is the same as the
p.value attribute assigned in the lexer module. So, PLUS will have the
value +.
For non-terminals, the value is determined by whatever is placed in p[0
]. If nothing is placed, the value is None. Also, p[1 ] is not the same as p[3
], since p is not a simple list (p[1 ] can specify embedded actions (not
discussed here)).
Note that the function can have any name, as long as it is preceded by p_.
The p_error(p) rule is defined to catch syntax errors (same as yyerror in
yacc/bison).
Multiple grammar rules can be combined into a single function, which is
a good idea if productions have a similar structure.
def p_binary_operators(p):
'''expression : expression PLUS term
precedence = (
('nonassoc' , 'LESSTHAN' , 'GREATERTHAN' ), # Nonassociative
operators ('left' , 'PLUS' , 'MINUS' ),
('left' , 'TIMES' , 'DIVIDE' ),
('right' , 'UMINUS' ), # Unary minus operator
)
Tokens are ordered from lowest to highest precedence. nonassoc means
that those tokens do not associate. This means that something like a < b <
is illegal whereas a < b is still legal.
parser .out is a debugging file that is created when the yacc program is
executed for the first time. Whenever a shift/reduce conflict occurs, the
parser always shifts.
import unittest
def tearDown(self ):
super (SomeTest, self ).tearDown() self .mock_data = []
# When the test finishes running, put the original method back. self
.addCleanup(my_patch.stop)
Another benefit of registering cleanups this way is that it allows the
programmer to put the cleanup code next to the setup code and it
protects you in the event that a subclasser forgets to call super in
tearDown.
The exception to check for must be the first parameter, and a callable
function must be passed as the second parameter. Any other parameters
specified will be passed directly to the function that is being called,
allowing you to specify the parameters that trigger the exception.
Programs throw errors when for instance wrong input is given. Because
of this, one needs to make sure that an error is thrown when actual
wrong input is given. Because of that we need to check for an exact
exception, for this example we will use the following exception:
class WrongInputException( Exception ): pass
This exception is raised when wrong input is given, in the following
context where we always expect a number as text input.
def convert2number(random_input): try :
my_input = int (random_input)
except ValueError :
raise WrongInputException("Expected an integer!" )
return my_input
1. Using the regular function call. The first argument takes the exception
type, second a callable (usually a function) and the rest of arguments are
passed to this callable.
2. Using a with clause, giving only the exception type to the function.
This has as advantage that more code can be executed, but should be
used with care since multiple functions can use the same exception which
can be problematic. An example: with
self.assertRaises(WrongInputException): convert2number("not a
number")
except WrongInputException:
self .fail()
There also may be a need to check for an exception which should not
have been thrown. However, a test will automatically fail when an
exception is thrown and thus may not be necessary at all. Just to show
the options, the second test method shows a case on how one can check
for an exception not to be thrown. Basically, this is catching the
exception and then failing the test using the fail method.
will fail. The assertTrue assertion is quite likely the most general
assertion, as anything tested can be cast as some boolean condition, but
often there are better alternatives. When testing for equality, as above, it
is better to write
self .assertEqual( 1 + 1 , 3 )
When the former fails, the message is
================================================================
FAIL: test (__main__.TruthTest)
---------------------------------------------------------------------
Traceback (most recent call last):
File "stuff.py", line 6, in test
self.assertTrue(1 + 1 == 3)
AssertionError: False is not true
but when the latter fails, the message is
================================================================
FAIL: test (__main__.TruthTest)
---------------------------------------------------------------------
Traceback (most recent call last):
File "stuff.py", line 6, in test
self.assertEqual(1 + 1, 3) AssertionError: 2 != 3
which is more informative (it actually evaluated the result of the left
hand side).
Note also that the assertions have negative forms. Thus assertEqual has
its negative counterpart assertNotEqual, and assertIsNone has its
negative counterpart assertIsNotNone. Once again, using the negative
counterparts when appropriate, will lead to clearer error messages.
stderr = PIPE)
err = result.stderr.read()
if err:
def docker_exec_something(something_file_string):
fl = Popen(["docker" , "exec" , "-i" , "something_cont" , "something" ],
stdin= PIPE, stdout= PIPE,
stderr= PIPE)
fl .stdin.write(something_file_string)
fl .stdin.close()
err = fl .stderr.read()
fl .stderr.close()
if err:
print (err)
exit()
result = fl .stdout.read()
print (result)
import os
from tempfile import NamedTemporaryFile import pytest
from subprocess import Popen, PIPE
class MockBytes():
'''Used to collect bytes '''
all_read = []
all_write = []
all_close = []
class MockPopen(object ):
def __init__ (self , args, stdout= None , stdin= None , stderr= None ):
all_popens.append(self )
self .args = args
self .byte_collection = MockBytes()
self .stdin = self .byte_collection
self .stdout = self .byte_collection
self .stderr = self .byte_collection
pass
def test_docker_install():
p = Popen(['which' , 'docker' ], stdout= PIPE, stderr= PIPE) result =
p.stdout.read()
assert 'bin/docker' in result
def test_copy_file_to_docker(all_popens):
result = copy_file_to_docker('asdf' , 'asdf' )
collected_popen = all_popens.pop()
mock_read, mock_write, mock_close =
collected_popen.byte_collection.get_all_mock_bytes() assert mock_read
assert result.args == ['docker' , 'cp' , 'asdf' , 'something_cont:asdf' ]
def test_docker_exec_something(all_popens):
docker_exec_something(something_file_string)
collected_popen = all_popens.pop()
mock_read, mock_write, mock_close =
collected_popen.byte_collection.get_all_mock_bytes() assert len
(mock_read) == 3
something_template_stdin = mock_write[0 ][1 ][0 ]
these = [os .environ['USER' ], os .environ['password_prod' ],
'table_name_here' , 'test_vdm' ,
running all the tests in the tests folder: py. test -k test_ tests
return multiples
We can test multiples_of alone by mocking out multiply. The below
example uses the Python standard library unittest, but this can be used
with other testing frameworks as well, like pytest or nose:
from unittest .mock import create_autospec import unittest
tests/test_code.py .
================================================ 1 passed
in 0.01 seconds
================================================
Section 193.2: Intro to Test Fixtures
More complicated tests sometimes need to have things set up before you
run the code you want to test. It is possible to do this in the test function
itself, but then you end up with large test functions doing so much that it
is difficult to tell where the setup stops and the test begins. You can also
get a lot of duplicate setup code between your various test functions.
Our code file:
def test_foo_updates():
my_stuff = stuff.Stuff() my_stuff.prep()
assert 1 == my_stuff.foo my_stuff.foo = 30000
assert my_stuff.foo == 30000
def test_bar_updates():
my_stuff = stuff.Stuff() my_stuff.prep()
assert 2 == my_stuff.bar my_stuff.bar = 42
assert 42 == my_stuff.bar
These are pretty simple examples, but if our Stuff object needed a lot
more setup, it would get unwieldy. We see that there is some duplicated
code between our test cases, so let's refactor that into a separate function
first.
def test_bar_updates():
my_stuff = get_prepped_stuff() assert 2 == my_stuff.bar my_stuff.bar = 42
assert 42 == my_stuff.bar
This looks better but we still have the my_stuff = get_prepped_stuff() call
cluttering up our test functions.
py.test fixtures to the rescue!
Fixtures are much more powerful and flexible versions of test setup
functions. They can do a lot more than we're leveraging here, but we'll
take it one step at a time.
@ pytest.fixture
def prepped_stuff():
my_stuff = stuff.Stuff()
my_stuff.prep()
return my_stuff
Now we should update the test functions so that they use the fixture. This
is done by adding a parameter to their definition that exactly matches
the fixture name. When py.test executes, it will run the fixture before
running the test, then pass the return value of the fixture into the test
function through that parameter. (Note that fixtures don't need to return
a value; they can do other setup things instead, like calling an external
resource, arranging things on the filesystem, putting values in a
database, whatever the tests need for setup)
Now you can see why we named it with a noun. but the my_stuff =
prepped_stuff line is pretty much useless, so let's just use prepped_stuff
directly instead.
We could add some code to call the clean up at the bottom of every test
function, but fixtures provide a better way to do this. If you add a
function to the fixture and register it as a finalizer, the code in the
finalizer function will get called after the test using the fixture is done. If
the scope of the fixture is larger than a single function (like module or
session), the finalizer will be executed after all the tests in scope are
completed, so after the module is done running or at the end of the entire
test running session.
@ pytest.fixture
def prepped_stuff(request): # we need to pass in the request to use
finalizers my_stuff = stuff.Stuff()
my_stuff.prep()
def fin(): # finalizer function
# do all the cleanup here
my_stuff.finish()
request.addfinalizer(fin) # register fin() as a finalizer
# you can do more setup here if you really want to
return my_stuff
@ pytest.yield_fixture
def prepped_stuff(): # it doesn't need request now! # do setup
my_stuff = stuff.Stuff()
my_stuff.prep()
# setup is done, pass control to the test functions
yield my_stuff
# do cleanup
my_stuff.finish()
And that concludes the Intro to Test Fixtures! For more information, see
the official py.test fixture documentation and the official yield fixture
documentation
$ py. test
================================================== test
session starts
===================================================
platform darwin -- Python 2.7.10, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /projectroot, inifile:
collected 1 items
tests/test_code.py F
========================================================
FAILURES
========================================================
___________________________________________________
test_add__failing
____________________________________________________
def test_add__failing():
> assert code .add(10 , 11 ) == 33
E assert 21 == 33
E + where 21 = < function add at 0x105d4d6e0 > (10 , 11 ) E + where <
function add at 0x105d4d6e0 > = code .add
tests/test_code.py: 5 : AssertionError
================================================ 1 failed
in 0.01 seconds
================================================
for i in range ( 50 ):
slow_func()
Using kernprof command to calculate profiling line by line
$ kernprof -lv so6.py
Wrote profile results to so6.py.lprof Timer unit: 4.27654e-07 s
Page request is almost always slower than any calculation based on the
information on the page.
: In many fields you can get 80% of the result with 20% of the effort
(also called the Remember the 80/20 rule
90/10 rule - it depends on who you talk to). Whenever you're about to
optimize code, use profiling to find out where that 80% of execution time
is going, so you know where to concentrate your effort.
Always run "before" and "after" benchmarks : How else will you know
that your optimizations actually made a difference? If your optimized
code turns out to be only slightly faster or smaller than the original
version, undo your changes and go back to the original, clear code.
Use the right algorithms and data structures: Don't use an O(n2) bubble
sort algorithm to sort a thousand elements when there's an O(n log n)
quicksort available. Similarly, don't store a thousand items in an array
that requires an O(n) search when you could use an O(log n) binary tree,
or an O(1) Python hash table.
1. The worst case time complexity of Insertion Sort is Θ(n^2). 2. The best
case time complexity of Insertion Sort is Θ(n).
The Big O notation is useful when we only have upper bound on time
complexity of an algorithm. Many times we easily find an upper bound
by simply looking at the algorithm. O(g(n)) = { f(n): there exist positive
constants c and n0 such that 0 <= f(n) <= cg(n) for all n >= n0}
First and foremost you should be able to find the bottleneck of your
script and note that no optimization can compensate for a poor choice in
data structure or a flaw in your algorithm design. Secondly do not try to
optimize too early in your coding process at the expense of
readability/design/quality. Donald Knuth made the following statement
on optimization:
"We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil. Yet we should not pass up
our opportunities in that critical 3%"
To profile your code you have several tools: cProfile (or the slower profile
) from the standard library, line_profiler and timeit . Each of them serve a
different purpose.
import cProfile
def f(x):
return "42!"
cProfile.run( 'f(12)' )
Or if you prefer to wrap parts of your existing code:
This will create outputs looking like the table below, where you can
quickly see where your program spends most of its time and identify the
functions to optimize.
3 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000
0.000 0.000 0.000 :1(f)
1 0.000 0.000 0.000 0.000 :1()
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
$ kernprof -l script_to_profile.py
@ profile
def slow_function(a , b , c): ...
The default behavior of kernprof is to put the results into a binary file
script_to_profile.py.lprof . You can tell kernprof to immediately view the
formatted results at the terminal with the [-v/--view] option. Otherwise,
you can view the results later like so:
Finally timeit provides a simple way to test one liners or small expression
both from the command line and the python shell. This module will
answer question such as, is it faster to do a list comprehension or use the
built-in list () when transforming a set into a list. Look for the setup
keyword or -s option to add setup code.
from a terminal
$ python -m timeit '"-".join(str(n) for n in range(100))' 10000 loops , best of
: 40.3 usec per loop
import hashlib
import os
salt = os .urandom( 16 )
hash = hashlib.pbkdf2_hmac( 'sha256' , b 'password' , salt , 100000 )
PBKDF2 can work with any digest algorithm, the above example uses
SHA256 which is usually recommended. The random salt should be
stored along with the hashed password, you will need it again in order to
compare an entered password to the stored hash. It is essential that each
password is hashed with a different salt. As to the number of rounds, it is
recommended to set it as high as possible for your application .
If you want the result in hexadecimal, you can use the binascii module:
import binascii
hexhash = binascii .hexlify( hash )
Note : While PBKDF2 isn't bad, bcrypt and especially scrypt are considered
stronger against brute-force attacks. Neither is part of the Python
standard library at the moment.
h = hashlib.new ('sha256' )
h.update(b'Nobody expects the Spanish Inquisition.' )
h.digest()
# ==>
b'.\xdf\xda\xdaVR[\x12\x90\xff\x16\xfb\x17D\xcf\xb4\x82\xdd)\x14\xff\xbc\xb6Iy\x0c\x
='
Note that you can call update an arbitrary number of times before
calling digest which is useful to hash a large file chunk by chunk. You
can also get the digest in hexadecimal format by using hexdigest:
h.hexdigest()
# ==>
'2edfdada56525b1290ff16fb1744cfb482dd2914ffbcb649790c0e589e462d3d'
import hashlib
hashlib.algorithms_available
# ==> {'sha256', 'DSA-SHA', 'SHA512', 'SHA224', 'dsaWithSHA', 'SHA',
'RIPEMD160', 'ecdsa-with-SHA1', 'sha1', 'SHA384', 'md5', 'SHA1',
'MD5', 'MD4', 'SHA256', 'sha384', 'md4', 'ripemd160', 'sha224', 'sha512',
'DSA', 'dsaEncryption', 'sha', 'whirlpool'}
The returned list will vary according to platform and interpreter; make
sure you check your algorithm is available.
There are also some algorithms that are guaranteed to be available on all
platforms and interpreters, which are available using
hashlib.algorithms_guaranteed:
hashlib.algorithms_guaranteed
# ==> {'sha256', 'sha384', 'sha1', 'sha224', 'md5', 'sha512'}
print hasher.hexdigest()
For larger files, a buffer of fixed length can be used:
import hashlib
SIZE = 65536
hasher = hashlib.new ('sha256' ) with open ('myfile' , 'r' ) as f:
import errno
# No private key, generate a new one. This can take a few seconds. key =
RSA.generate(4096 )
with open ('privkey.pem' , 'wb' ) as f:
f.write(key.exportKey( 'PEM' ))
with open ('pubkey.pem' , 'wb' ) as f:
f.write(key.publickey().exportKey('PEM' ))
Verifying the signature works similarly but uses the public key rather
than the private key:
Note : The above examples use PKCS#1 v1.5 signing algorithm which is
very common. pycrypto also implements the newer PKCS#1 PSS
algorithm, replacing PKCS1_v1_5 by PKCS1_PSS in the examples
should work if you want to use that one. Currently there seems to be
little reason to use it however.
The recipient can decrypt the message then if they have the right private
key:
iv = derived[0 :IV_SIZE]
key = derived[IV_SIZE:]
cleartext = AES.new (key, AES.MODE_CFB,
iv).decrypt(encrypted[SALT_SIZE:])
Exceptions are powerful, but a single overzealous except clause can take
it all away in a single line.
try: res = get_result() res = res[0] log('got result: %r' % res) except: if
not res: res = '' print('got exception')
This example demonstrates 3 symptoms of the antipattern:
1. The except with no exception type (line 5) will catch even healthy
exceptions, including KeyboardInterrupt . That will prevent the
program from exiting in some cases.
2. The except block does not reraise the error, meaning that we won't be
able to tell if the exception came from within get_result or because res
was an empty list.
3. Worst of all, if we were worried about result being empty, we've
caused something much worse. If get_result fails, res will stay completely
unset, and the reference to res in the except block, will raise NameError ,
completely masking the original error.
Always think about the type of exception you're trying to handle. Give
the exceptions page a read and get a feel for what basic exceptions exist.
Here is a fixed version of the example above:
import traceback try: res = get_result() except Exception:
log_exception(traceback.format_exc()) raise try: res = res[0] except
IndexError: res = '' log('got result: %r' % res)
We catch more specific exceptions, reraising where necessary. A few
more lines, but infinitely more correct.
return None
return integer_output
And it could be used in the following way:
x=5
if intensive_f(x) is not None :
print (intensive_f(x) / 2 )
else :
print (x , "could not be processed" )
print (x)
Whilst this will work, it has the problem of calling intensive_f, which
doubles the length of time for the code to run. A better solution would be
to get the return value of the function beforehand.
x=5
result = intensive_f(x)
if result is not None :
print (result / 2 )
else :
print (x, "could not be processed" )
print (speed)
with:
bird_speeds = get_very_long_dictionary()
print (speed)
The first example has to look through the dictionary twice, and as this is
a long dictionary, it may take a long time to do so each time. The second
only requires one search through the dictionary, and thus saves a lot of
processor time.
This section will show you some issues that you might encounter when
writing Python code.
li[ 0 ].append(1 )
print (li)
# Out: [[1], [1], [1]]
The reason is that [[]] * 3 doesn't create a list of 3 different list s. Rather,
it creates a list holding 3 references to the same list object. As such, when
we append to li[0 ] the change is visible in all sub-elements of li. This is
equivalent of:
li = []
element = [[]]
li = element + element + element
print (li)
# Out: [[], [], []]
element.append(1 )
print (li)
# Out: [[1], [1], [1]]
li = [[]] * 3
print ([id (inner_list) for inner_list in li]) # Out: [6830760, 6830760,
6830760]
>>> li = []
>>> li.append([])
>>> li.append([])
>>> li.append([])
>>> for k in li: print (id (k)) ...
4315469256
4315564552
4315564808
Do:
Python is dynamically typed, therefore checking for type makes you lose
flexibility. Instead, use duck typing by checking behavior. If you expect a
string in a function, then use str () to convert any object to a string. If
you expect a list, use list () to convert any iterable to a list.
Don't:
def foo(name):
if isinstance (name , str ): print (name.lower())
def bar(listing):
if isinstance (listing, list ): listing.extend((1 , 2 , 3 )) return ", " .join(listing)
Do:
def foo(name) :
print ( str (name).lower())
def bar(listing) :
l = list (listing) l.extend((1 , 2 , 3 )) return ", " .join(l)
Using the last way, foo will accept any object. bar will accept strings,
tuples, sets, lists and much more. Cheap DRY.
Don't mix spaces and tabs Use object as first parent
This is tricky, but it will bite you as your program grows. There are old
and new classes in Python 2 .x. The old ones are, well, old. They lack
some features, and can have awkward behavior with inheritance. To be
usable, any of your class must be of the "new style". To do so, make it
inherit from object .
Don't:
class Father: pass
class Child(Father): pass
Do:
class Father( object ): pass
class Child(Father): pass
In Python 3 .x all classes are new style so you don't need to do that.
Don't initialize class attributes outside the init method
Do:
class Car(object ):
def __init__ (self ):
self .color = "red"
self .wheels = [Wheel(), Wheel(), Wheel(), Wheel()]
x = []
foo(li= x) # Out: [1]
# Iteration #1
index = 0
alist = [0 , 1 , 2 ]
alist.pop(0 ) # removes '0'
# Iteration #2
index = 1
alist = [1 , 2 ]
alist.pop(1 ) # removes '2'
alist = [1 , 2 , 3 , 4 , 5 , 6 , 7 ]
for index, item in reversed (list (enumerate (alist))): # delete all even items
if item % 2 == 0 :
alist.pop(index)
print (alist)
# Out: [1, 3, 5, 7]
By iterating through the loop starting at the end, as items are removed
(or added), it does not affect the indices of items earlier in the list. So this
example will properly remove all items that are even from alist.
A similar problem arises when inserting or appending elements to a list
that you are iterating over, which can result in an infinite loop:
alist = [0 , 1 , 2 ]
for index, value in enumerate (alist):
# break to avoid infinite loop:
if index == 20 :
break
alist.insert(index, 'a' )
print (alist)
# Out (abbreviated): ['a', 'a', ..., 'a', 'a', 0, 1, 2]
Without the break condition the loop would insert 'a' as long as the
computer does not run out of memory and the program is allowed to
continue. In a situation like this, it is usually preferred to create a new
list, and add items to the new list as you loop through the original list.
When using a for loop, you cannot modify the list elements with the
placeholder variable:
alist = [ 1 , 2 , 3 , 4 ] for item in alist: if item % 2 == 0 :
zlist = [0 , 1 , 2 ]
while zlist:
print (zlist[0 ])
zlist.pop(0 )
print ('After: zlist =' , zlist)
# Out: 0
#1
#2
# After: zlist = []
zlist = [0 , 1 , 2 ]
x=1
while len (zlist) > x:
print (zlist[ 0 ])
zlist.pop( 0 )
print ( 'After: zlist =' , zlist)
# Out: 0
#1
# After: zlist = [2]
zlist = [1 , 2 , 3 , 4 , 5 ]
i=0
while i < len (zlist):
if zlist[i] % 2 == 0 : zlist.pop(i)
else :
i += 1 print (zlist)
# Out: [1, 3, 5]
Here we are funneling desired results into a new list. We can then
optionally reassign the temporary list to the original variable.
With this trend of thinking, you can invoke one of Python's most elegant
and powerful features, list comprehensions, which eliminates temporary
lists and diverges from the previously discussed in-place list/index
mutation ideology.
zlist = [1 , 2 , 3 , 4 , 5 ]
[item for item in zlist if item % 2 != 0 ] # Out: [1, 3, 5]
>>> 8 is (7 - 1 )
False
>>> 3 is (2 - 1 )
True
Wait what?
We can see that the identity operation is yields True for some integers (-3,
256 ) but no for others (-8, 257 ).
To be more specific, integers in the range [ 5 , 256 ] are internally cached
during interpreter startup and are only created once. As such, they are
identical and comparing their identities with is yields True ; integers
outside this range are (usually) created on-the-fly and their identities
compare to False . This is a common pitfall since this is a common range
for testing, but often enough, the code fails in the later staging process
(or worse - production) with no apparent reason after working perfectly
in development.
The solution is to always compare values using the equality (==) operator
and not the identity (is) operator.
Python also keeps references to commonly used strings and can result in
similarly confusing behavior when comparing identities (i.e. using is) of
strings.
>>> 'python' is 'py' + 'thon' True
The string 'python' is commonly used, so Python has one object that all
references to the string 'python' use.
For uncommon strings, comparing identity fails even when the strings
are equal.
>>> 'this is not a common string' is 'this is not' + ' a common string' False
>>> 'this is not a common string' == 'this is not' + ' a common string' True
So, just like the rule for Integers, always compare string values using the
equality (==) operator and not the identity (is) operator.
a = [i for i in range ( 3 )]
print (i) # Outputs 2
This occurs only in Python 2 due to the fact that the list comprehension
“leaks” the loop control variable into the surrounding scope ( source ).
This behavior can lead to hard-to-find bugs and it has been fixed in
Python 3 .
Python 3.x Version ≥ 3.0
i=0
a = [i for i in range (3 )] print (i) # Outputs 0
Similarly, for loops have no private scope for their iteration variable
i=0
for i in range ( 3 ): pass
print (i) # Outputs 2
This type of behavior occurs both in Python 2 and Python 3. To avoid
issues with leaking variables, use new variables in list comprehensions
and for loops as appropriate.
x=7
x.bit_length() # Out: 3
Seeing the above code works, you might intuitively think that 7
.bit_length() would work as well, only to find out it raises a SyntaxError
. Why? because the interpreter needs to differentiate between an
attribute access and a floating number (for example 7.2 or 7
.bit_length()). It can't, and that's why an exception is raised.
Using two dots (like this 7 ..bit_length()) doesn't work in this case, because
that creates a float literal and floats don't have the bit_length() method.
This problem doesn't exist when accessing float literals' attributes since
the interpreter is "smart" enough to know that a float literal can't contain
two ., for example:
7.2 .as_integer_ratio()
# Out: (8106479329266893, 1125899906842624)
num = 600000
t = Thread(target= calc_fact, daemon= True , args= [num])
print ("About to calculate: {}!" .format(num))
t.start()
print ("Calculating..." )
t.join()
print ("Calculated" )
You would expect to see Calculating... printed out immediately after the
thread is started, we wanted the calculation to happen in a new thread
after all! But in actuality, you see it get printed after the calculation is
complete. That is because the new thread relies on a C function (math
.factorial) which will lock the GIL while it executes.
There are a couple ways around this. The first is to implement your
factorial function in native Python. This will allow the main thread to
grab control while you are inside your loop. The downside is that this
solution will be a lot slower, since we're not using the C function
anymore.
def calc_fact(num):
""" A slow version of factorial in native Python """ res = 1
while num >= 1 :
You can also sleep for a period of time before starting your execution.
Note: this won't actually allow your program to interrupt the
computation happening inside the C function, but it will allow your main
thread to continue after the spawn, which is what you may expect.
my_var = 'bla' ;
api_key = 'key' ;
...lots of code here...
params = {"language" : "en" , my_var: api_key}
}
In Python, however, it would result in the following dictionary:
class Vector(object ):
def __init__ (self , x, y):
self .x = x
self .y = y
a = Vector( 3 , 5 )
b = Vector( 2 , 7 )