1. Trang chủ
  2. » Công Nghệ Thông Tin

AMECO python book 2017 FUNDAMENTALS OF PYTHON Industry 4 0 Innovation LABIndustry

670 2 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 670
Dung lượng 12,13 MB

Nội dung

FUNDAMENTALS OF PYTHON Industry 4 0 Innovation LABIndustry 4 0 Innovation LAB Fundamentals of Programming Python DRAFT Richard L Halterman Southern Adventist University November 30, 2017 Fundamentals.

FUNDAMENTALS OF PYTHON Industry 4.0 Innovation LAB Fundamentals of Python Programming D T F RA Richard L Halterman Southern Adventist University November 30, 2017 Fundamentals of Python Programming Copyright © 2017 Richard L Halterman All rights reserved See the preface for the terms of use of this document i Contents The Context of Software Development 1.1 Software 1.2 Development Tools 1.3 Learning Programming with Python 1.4 Writing a Python Program 1.5 The Python Interactive Shell 1.6 A Longer Python program 11 1.7 Exercises 12 Values and Variables 13 2.1 Integer and String Values 13 2.2 Variables and Assignment 17 2.3 Identifiers 24 2.4 Floating-point Numbers 26 2.5 Control Codes within Strings 30 2.6 User Input 31 2.7 Controlling the print Function 34 2.8 String Formatting 35 2.9 Multi-line Strings 39 2.10 Exercises 40 Expressions and Arithmetic 43 3.1 Expressions 43 3.2 Mixed Type Expressions 49 3.3 Operator Precedence and Associativity 49 3.4 Formatting Expressions 51 ©2017 Richard L Halterman Draft date: November 30, 2017 ii CONTENTS 3.5 Comments 52 3.6 Errors 53 3.6.1 Syntax Errors 53 3.6.2 Run-time Exceptions 54 3.6.3 Logic Errors 56 3.7 Arithmetic Examples 57 3.8 More Arithmetic Operators 59 3.9 Algorithms 61 3.10 Exercises 62 Conditional Execution 67 4.1 Boolean Expressions 67 4.2 Boolean Expressions 68 4.3 The Simple if Statement 69 4.4 The if/else Statement 75 4.5 Compound Boolean Expressions 77 4.6 The pass Statement 80 4.7 Floating-point Equality 82 4.8 Nested Conditionals 83 4.9 Multi-way Decision Statements 93 4.10 Multi-way Versus Sequential Conditionals 97 4.11 Conditional Expressions 99 4.12 Errors in Conditional Statements 102 4.13 Logic Complexity 105 4.14 Exercises 107 Iteration 113 5.1 The while Statement 113 5.2 Definite Loops vs Indefinite Loops 121 5.3 The for Statement 122 5.4 Nested Loops 126 5.5 Abnormal Loop Termination 132 5.6 5.5.1 The break statement 133 5.5.2 The continue Statement 136 while/else and for/else 137 ©2017 Richard L Halterman Draft date: November 30, 2017 iii CONTENTS 5.7 Infinite Loops 139 5.8 Iteration Examples 143 5.9 5.8.1 Computing Square Root 143 5.8.2 Drawing a Tree 144 5.8.3 Printing Prime Numbers 146 5.8.4 Insisting on the Proper Input 150 Exercises 150 Using Functions 157 6.1 Introduction to Using Functions 158 6.2 Functions and Modules 162 6.3 The Built-in Functions 164 6.4 Standard Mathematical Functions 167 6.5 time Functions 170 6.6 Random Numbers 173 6.7 System-specific Functions 176 6.8 The eval and exec Functions 176 6.9 Turtle Graphics 179 6.10 Other Techniques for Importing Functions and Modules 185 6.11 Exercises 191 Writing Functions 193 7.1 Function Basics 194 7.2 Parameter Passing 209 7.3 Documenting Functions 211 7.4 Function Examples 213 7.4.1 Better Organized Prime Generator 213 7.4.2 Command Interpreter 215 7.4.3 Restricted Input 216 7.4.4 Better Die Rolling Simulator 218 7.4.5 Tree Drawing Function 219 7.4.6 Floating-point Equality 220 7.5 Refactoring to Eliminate Code Duplication 222 7.6 Custom Functions vs Standard Functions 224 7.7 Exercises 227 ©2017 Richard L Halterman Draft date: November 30, 2017 CONTENTS More on Functions iv 233 8.1 Global Variables 233 8.2 Default Parameters 238 8.3 Introduction to Recursion 241 8.4 Making Functions Reusable 246 8.5 Functions as Data 249 8.6 Separating Concerns with Pluggable Modules 253 8.7 Lambda Expressions 273 8.8 Generators 278 8.9 Local Function Definitions 286 8.10 Decorators 292 8.11 Partial Application 303 8.12 Exercises 306 Objects 311 9.1 Using Objects 311 9.2 String Objects 312 9.3 File Objects 316 9.4 Fraction Objects 323 9.5 Turtle Graphics Objects 325 9.6 Graphics with tkinter Objects 326 9.7 Other Standard Python Objects 332 9.8 Object Mutability and Aliasing 332 9.9 Garbage Collection 336 9.10 Exercises 337 10 Lists 339 10.1 Using Lists 341 10.2 List Traversal 345 10.3 Building Lists 346 10.4 List Membership 351 10.5 List Assignment and Equivalence 352 10.6 List Bounds 357 10.7 Slicing 358 10.8 List Element Removal 361 ©2017 Richard L Halterman Draft date: November 30, 2017 CONTENTS v 10.9 Lists and Functions 362 10.10 List Methods 363 10.11 Prime Generation with a List 366 10.12 Command-line Arguments 368 10.13 List Comprehensions 369 10.14 Multidimensional Lists 375 10.15 Summary of List Creation Techniques 384 10.16 Lists vs Generators 385 10.17 Exercises 385 11 Tuples, Dictionaries, and Sets 389 11.1 Tuples 389 11.2 Arbitrary Argument Lists 393 11.3 Dictionaries 398 11.4 Using Dictionaries 402 11.5 Counting with Dictionaries 404 11.6 Grouping with Dictionaries 408 11.7 Keyword Arguments 411 11.8 Sets 414 11.9 Set Quantification with all and any 415 11.10 Enumerating the Elements of a Data Structure 419 11.11 Exercises 421 12 Handling Exceptions 425 12.1 Motivation 425 12.2 Common Standard Exceptions 426 12.3 Handling Exceptions 428 12.4 Handling Multiple Exceptions 431 12.5 The Catch-all Handler 432 12.6 Catching Exception Objects 436 12.7 Exception Handling Scope 437 12.8 Raising Exceptions 446 12.9 The try Statement’s Optional else Block 451 12.10 finally block 453 12.11 Using Exceptions Wisely 457 ©2017 Richard L Halterman Draft date: November 30, 2017 vi CONTENTS 12.12 Exercises 458 13 Custom Types 463 13.1 Circle Objects 463 13.2 Restricting Access to Members 473 13.3 Rational Numbers 474 13.4 Bank Account Objects 479 13.5 Stopwatch Objects 483 13.6 Traffic Light Objects 486 13.7 Automated Testing 492 13.8 Plotting Data 497 13.9 Dynamic Content 502 13.10 Class Variables 506 13.11 Exercises 507 14 Class Design: Composition and Inheritance 513 14.1 Composition 513 14.2 Class Inheritance 518 14.3 Composition vs Inheritance 537 14.4 Multiple Inheritance 540 14.5 Unit Testing 558 14.6 Custom Exceptions 563 14.7 Exercises 566 15 Algorithm Quality 567 15.1 Good Algorithms Versus Bad Algorithms 567 15.2 Sorting 576 15.3 Flexible Sorting 580 15.4 Search 582 15.4.1 Linear Search 582 15.4.2 Binary Search 584 15.5 Recursion Revisited 593 15.6 List Permutations 600 15.7 Randomly Permuting a List 609 15.8 Reversing a List 614 ©2017 Richard L Halterman Draft date: November 30, 2017 CONTENTS vii 15.9 Memoization 615 15.10 Exercises 628 16 Representing Relationships with Graphs 631 16.1 Introduction to Graphs 631 16.2 Implementing Graphs in Python 635 16.3 Path Finding 635 16.4 Breadth-first Search 637 16.5 Depth-first Search 647 16.6 Exercises 654 Index ©2017 Richard L Halterman 655 Draft date: November 30, 2017 644 16.4 BREADTH-FIRST SEARCH """ Performs a breadth-first traversal of graph originating at start_vertex and ending when the traversal encounters end_vertex If the end_vertex parameter is omitted, the BFS continues to all vertices in the graph If the start_vertex parameter is omitted, the BFS begins with an arbitrary vertex in the graph Builds and returns a dictionary with vertices mapped to their immediate predecessors on the breadth-first traversal """ # A dictionary of vertex predecessors encountered on a breadth-first # traversal from start_vertex to end_vertex # The dictionary key is a vertex, and the associated value is # the vertex that comes immediately before the key on a # breadth-first traversal # This dictionary initially is empty, and we will add vertices as # we "visit" them during the breadth-first traversal predecessor = {} if graph: if not start_vertex: # Caller provided a starting vertex? start_vertex = list(graph.keys())[0] # Grab an arbitrary vertex from the graph #print("Start vertex:", start_vertex) # Make an empty queue and insert the starting vertex # The algorithm will extract and visit vertices from this queue q = Queue() q.put(start_vertex) # Keep searching while the queue holds vertices yet to visit # and we have yet to visit our destination vertex while not q.empty() and end_vertex not in predecessor: vertex = q.get() # Get vertex on the front of the queue for adjacent_vertex in graph[vertex]: # Consider all adjacent vertices # Has the predecessor of this vertex been established? if adjacent_vertex not in predecessor: q.put(adjacent_vertex) # Enqueue the vertex # Register which vertex should come immediately before this # one on a shortest path (this "visits" the vertex) #print(adjacent_vertex, "< ", vertex) predecessor[adjacent_vertex] = vertex # At this point we exited the while loop because either the queue was # empty or the destination vertex now is in the predecessor dictionary # (or both) If the queue is empty but the destination vertex is not in # the predecessor dictionary, the destination vertex is unreachable from the # starting vertex If the queue is not empty but the destination vertex # is in the predecessor dictionary, the path from the starting vertex to # the destination vertex exists and excludes one or more vertices in # the graph If the queue is empty and the destination vertex is in the # predecessor dictionary, the shortest path from the starting vertex to the # destination vertex includes all vertices reachable from the starting # vertex return predecessor ©2017 Richard L Halterman Draft date: November 30, 2017 645 16.4 BREADTH-FIRST SEARCH def find_path(graph, start_vertex, end_vertex): """ Builds a list of vertices in order along the shortest path from a starting vertex to an ending vertex in a graph graph: The graph to traverse start_vertex: The starting vertex end_vertex: The vertex to locate """ # Compute predecessor of each vertex on a shortest path # Call the bfs function to build the predecessor dictionary predecessor = bfs(graph, start_vertex, end_vertex) path = [] # Path initially empty # Check that we were able to reach the destination vertex if end_vertex in predecessor: # Start at the end and work backwards path = [end_vertex] vertex = end_vertex # Keep going until we get to the beginning of the path while vertex != start_vertex: # Get vertex that comes immediately before on a shortest path vertex = predecessor[vertex] # Prepend the predecessor vertex to the front of the path list path = [vertex] + path return path def is_connected(G): """ Returns True if G is a dictionary representing a connected graph; otherwise, returns False A graph containing no vertices (and, therefore, no edges) is considered connected """ # Use bfs to compute the predecessor of each vertex on a # shortest path from an arbitrary vertex within G predecessor = bfs(G) for vertex in G: if vertex not in predecessor: return False return True def main(): """ Tests the find_path and is_connected functions """ # Dictionary representing routes = { "ATL": {"MIA", "MIA": {"LGA", "DFW": {"LAX", "LAX": {"SFO", "DEN": {"SFO", "SEA": {"SFO", ©2017 Richard L Halterman the graph of airline routes "DCA", "DCA", "DEN", "DEN", "LAX", "DEN", "ORD", "ATL", "MCI", "MCI", "MCI", "ORD", "MCI", "DFW", "DEN"}, "DFW"}, "ORD", "ATL", "MIA"}, "DFW"}, "DFW", "SEA", "ATL"}, "LGA"}, Draft date: November 30, 2017 646 16.4 BREADTH-FIRST SEARCH } r1 = { } r2 = { } "MCI": "ORD": "DCA": "LGA": "SFO": "CLT": "BNA": "CHA": "ATL": "MIA": "DFW": "LAX": "DEN": "SEA": "MCI": "ORD": "DCA": "LGA": "SFO": {"DEN", {"SEA", {"ORD", {"SEA", {"SEA", {"BNA", {"CLT", {"CLT", {"MIA", {"LGA", {"LAX", {"SFO", {"SFO", {"SFO", {"DEN", {"SEA", {"ORD", {"SEA", {"SEA", "LAX", "DFW", "ATL", "ORD", "LGA"}, "MCI", "DFW", "ATL", "DCA", "LGA"}, "ATL", "MIA", "LGA"}, "MCI", "ORD", "DCA", "MIA"}, "DEN", "LAX"}, "CHA"}, "CHA"}, "BNA"} "DCA", "DCA", "DEN", "DEN", "LAX", "DEN", "LAX", "MCI", "ATL", "MCI", "DEN", "ORD", "ATL", "MCI", "MCI", "MCI", "ORD", "DFW", "DFW", "MIA", "ORD", "LAX"} "MCI", "DFW", "DEN"}, "DFW"}, "ORD", "ATL", "MIA"}, "DFW"}, "DFW", "SEA", "ATL"}, "LGA"}, "ATL", "ORD", "LGA"}, "ATL", "DCA", "LGA"}, "LGA"}, "DCA", "MIA"}, "CLT": {"BNA", "CHA"}, "BNA": {"CLT", "CHA"}, "CHA": {"CLT", "BNA"} # Find shortest paths, as before print(find_path(routes, "LAX", "DCA")) print(find_path(routes, "MIA", "SFO")) print(find_path(routes, "ATL", "MIA")) print(find_path(routes, "LGA", "LGA")) print(find_path(routes, "CLT", "BNA")) print(find_path(routes, "BNA", "ATL")) # Check connectivity print("Connected: ", is_connected(routes)) print("Connected: ", is_connected(r1)) print("Connected: ", is_connected(r2)) if name == " main ": main() In Listing 16.2 (checkconnected.py) the graph routes is not connected, but r1 and r2 are both connected (not to each other, though) The execution of Listing 16.2 (checkconnected.py) prints ['LAX', ['MIA', ['ATL', ['LGA'] ['CLT', [] 'MCI', 'ATL', 'DCA'] 'LGA', 'SEA', 'SFO'] 'MIA'] 'BNA'] ©2017 Richard L Halterman Draft date: November 30, 2017 16.5 DEPTH-FIRST SEARCH Connected: Connected: Connected: 647 False True True Observe that we made no changes to find_path, and yet it still works correctly with our modified bfs function 16.5 Depth-first Search When traversing a graph an alternative to breadth-first search is depth-first search (DFS) BFS conservatively visits vertices at increasing distances, never venturing farther away until all closer options are exhausted DFS, on the other hand, traces a path that moves as far away from the starting vertex as possible DFS backs up to consider other paths only when it can go no further It can proceed no further when it reaches a vertex connected only to already visited vertices At this point it must back up to its most recently visited vertex and consider another path It then continues its effort to move as far as possible away the starting vertex The BFS algorithm uses a queue to guide its traversal DFS uses a different accessory data structure—a stack A stack is a linear data structure with restricted access like a queue, but, unlike a queue, a stack permits removal of only the most recently added element A stack, therefore, is a last-in, first out (LIFO) container Unlike the Queue class, Python does not have a standard stack class Fortunately, we can use a regular list object in a disciplined way to perfectly model a stack Lists support random access; that is, we can access an element at any index In order to model a stack we must limit our efforts to modify a list to two list methods: • append places an element onto the top (end) of the stack • pop removes and returns the top (end) stack element The list class has no empty method to determine if the list contains any elements, but we can use the len function and compare its result to zero We can practice with our stack in the interactive interpreter: >>> s = [] >>> len(s) >> s.append(34) >>> len(s) >> s.append("Hello") >>> s.append(12) >>> s.append([10, 20, 30]) >>> s.pop() [10, 20, 30] >>> s.pop() 12 >>> len(s) >> s.pop() 'Hello' ©2017 Richard L Halterman Draft date: November 30, 2017 648 16.5 DEPTH-FIRST SEARCH >>> s.pop() 34 >>> len(s) and end_vertex not in visited: vertex = s.pop() # Get vertex on the top of the stack if vertex not in visited: visited.add(vertex) # Visit the vertex for adjacent_vertex in graph[vertex]: # Consider all adjacent vertices # Has the predecessor of this vertex been established? if adjacent_vertex not in visited: s.append(adjacent_vertex) # Push the vertex # At this point we exited the while loop because either the stack was # empty or the destination vertex now is in the visited set (or both) # If the stack is empty but the destination vertex is not in # the visited set, the destination vertex is unreachable from the # starting vertex If the stack is not empty but the destination vertex # is in the visited set, the path from the starting vertex to # the destination vertex exists and excludes one or more vertices in # the graph If the stack is empty and the destination vertex is in the # visited set, the shortest path from the starting vertex to the # destination vertex includes all vertices reachable from the starting # vertex return visited def dfs2(graph, start_vertex=None, end_vertex=None): """ Performs a depth-first traversal of graph originating at start_vertex and ending when the traversal encounters end_vertex If the end_vertex parameter is omitted, the DFS continues to all vertices in the graph If the start_vertex parameter is omitted, the DFS begins with an arbitrary vertex in the graph Builds and returns a set of vertices discovered during the depth-first traversal """ # A set of vertices encountered on a depth-first # traversal from start_vertex to end_vertex # This set initially is empty, and we will add vertices as # we "visit" them during the depth-first traversal visited = set() def dfs3(start_vertex, end_vertex): visited.add(start_vertex) for adjacent_vertex in graph[start_vertex]: if adjacent_vertex not in visited and end_vertex not in visited: dfs3(adjacent_vertex, end_vertex) ©2017 Richard L Halterman Draft date: November 30, 2017 651 16.5 DEPTH-FIRST SEARCH if graph: if not start_vertex: # Caller provided a starting vertex? start_vertex = list(graph.keys())[0] # Grab an arbitrary vertex from the graph dfs3(start_vertex, end_vertex) # Build the visited set return visited def bfs(graph, start_vertex=None, end_vertex=None): """ Performs a breadth-first traversal of graph originating at start_vertex and ending when the traversal encounters end_vertex If the end_vertex parameter is omitted, the BFS continues to all vertices in the graph If the start_vertex parameter is omitted, the BFS begins with an arbitrary vertex in the graph Builds and returns a dictionary with vertices mapped to their immediate predecessors on the breadth-first traversal """ # A dictionary of vertex predecessors encountered on a breadth-first # traversal from start_vertex to end_vertex # The dictionary key is a vertex, and the associated value is # the vertex that comes immediately before the key on a # breadth-first traversal # This dictionary initially is empty, and we will add vertices as # we "visit" them during the breadth-first traversal predecessor = {} if graph: if not start_vertex: # Caller provided a starting vertex? start_vertex = list(graph.keys())[0] # Grab an arbitrary vertex from the graph #print("Start vertex:", start_vertex) # Make an empty queue and insert the starting vertex # The algorithm will extract and visit vertices from this queue q = Queue() q.put(start_vertex) # Keep searching while the queue holds vertices yet to visit # and we have yet to visit our destination vertex while not q.empty() and end_vertex not in predecessor: vertex = q.get() # Get vertex on the front of the queue for adjacent_vertex in graph[vertex]: # Consider all adjacent vertices # Has the predecessor of this vertex been established? if adjacent_vertex not in predecessor: q.put(adjacent_vertex) # Enqueue the vertex # Register which vertex should come immediately before this # one on a shortest path (this "visits" the vertex) #print(adjacent_vertex, "< ", vertex) predecessor[adjacent_vertex] = vertex # At this point we exited the while loop because either the queue was # empty or the destination vertex now is in the predecessor dictionary # (or both) If the queue is empty but the destination vertex is not in ©2017 Richard L Halterman Draft date: November 30, 2017 652 16.5 DEPTH-FIRST SEARCH # # # # # # # # the predecessor dictionary, the destination vertex is unreachable from the starting vertex If the queue is not empty but the destination vertex is in the predecessor dictionary, the path from the starting vertex to the destination vertex exists and excludes one or more vertices in the graph If the queue is empty and the destination vertex is in the predecessor dictionary, the shortest path from the starting vertex to the destination vertex includes all vertices reachable from the starting vertex return predecessor def find_path(graph, start_vertex, end_vertex): """ Builds a list of vertices in order along the shortest path from a starting vertex to an ending vertex in a graph graph: The graph to traverse start_vertex: The starting vertex end_vertex: The vertex to locate """ # Compute predecessor of each vertex on a shortest path # Call the bfs function to build the predecessor dictionary predecessor = bfs(graph, start_vertex, end_vertex) path = [] # Path initially empty # Check that we were able to reach the destination vertex if end_vertex in predecessor: # Start at the end and work backwards path = [end_vertex] vertex = end_vertex # Keep going until we get to the beginning of the path while vertex != start_vertex: # Get vertex that comes immediately before on a shortest path vertex = predecessor[vertex] # Prepend the predecessor vertex to the front of the path list path = [vertex] + path return path def is_connected(G): """ Returns True if G is a dictionary representing a connected graph; otherwise, returns False A graph containing no vertices (and, therefore, no edges) is considered connected """ # Use bfs to compute the predecessor of each vertex on a # shortest path from an arbitrary vertex within G predecessor = dfs2(G) #predecessor = bfs(G) for vertex in G: if vertex not in predecessor: return False return True def is_connected2(G): ©2017 Richard L Halterman Draft date: November 30, 2017 653 16.5 DEPTH-FIRST SEARCH """ G is a dictionary that represents a graph """ for v in G: # Examine each dictionary key (vertex) for w in G: # Examine each dictionary key (vertex) if v != w and w not in bfs(G, v, w): return False # Vertex w not reachable from vertex v return True # All vertices in G are reachable from any vertex in G def main(): """ Tests the find_path and is_connected functions """ # Dictionary representing routes = { "ATL": {"MIA", "MIA": {"LGA", "DFW": {"LAX", "LAX": {"SFO", "DEN": {"SFO", "SEA": {"SFO", "MCI": {"DEN", "ORD": {"SEA", "DCA": {"ORD", "LGA": {"SEA", "SFO": {"SEA", "CLT": {"BNA", "BNA": {"CLT", "CHA": {"CLT", } r1 = { } r2 = { } "ATL": "MIA": "DFW": "LAX": "DEN": "SEA": "MCI": "ORD": "DCA": "LGA": "SFO": {"MIA", {"LGA", {"LAX", {"SFO", {"SFO", {"SFO", {"DEN", {"SEA", {"ORD", {"SEA", {"SEA", the graph of airline routes "DCA", "ORD", "MCI", "DFW", "DEN"}, "DCA", "ATL", "DFW"}, "DEN", "MCI", "ORD", "ATL", "MIA"}, "DEN", "MCI", "DFW"}, "LAX", "MCI", "DFW", "SEA", "ATL"}, "DEN", "ORD", "LGA"}, "LAX", "DFW", "ATL", "ORD", "LGA"}, "MCI", "DFW", "ATL", "DCA", "LGA"}, "ATL", "MIA", "LGA"}, "MCI", "ORD", "DCA", "MIA"}, "DEN", "LAX"}, "CHA"}, "CHA"}, "BNA"} "DCA", "DCA", "DEN", "DEN", "LAX", "DEN", "LAX", "MCI", "ATL", "MCI", "DEN", "ORD", "ATL", "MCI", "MCI", "MCI", "ORD", "DFW", "DFW", "MIA", "ORD", "LAX"} "MCI", "DFW", "DEN"}, "DFW"}, "ORD", "ATL", "MIA"}, "DFW"}, "DFW", "SEA", "ATL"}, "LGA"}, "ATL", "ORD", "LGA"}, "ATL", "DCA", "LGA"}, "LGA"}, "DCA", "MIA"}, "CLT": {"BNA", "CHA"}, "BNA": {"CLT", "CHA"}, "CHA": {"CLT", "BNA"} # Find shortest paths, as before print(find_path(routes, "LAX", "DCA")) print(find_path(routes, "MIA", "SFO")) print(find_path(routes, "ATL", "MIA")) print(find_path(routes, "LGA", "LGA")) ©2017 Richard L Halterman Draft date: November 30, 2017 654 16.6 EXERCISES print(find_path(routes, "CLT", "BNA")) print(find_path(routes, "BNA", "ATL")) # Check connectivity print("Connected: ", is_connected(routes), is_connected2(routes)) print("Connected: ", is_connected(r1), is_connected2(r1)) print("Connected: ", is_connected(r2), is_connected2(r2)) if name == " main ": main() Because of the way it works, DFS is not useful for finding the shortest path between to vertices Many useful graph algorithms involve variations of BFS or DFS 16.6 Exercises CAUTION! SECTION UNDER CONSTRUCTION Add item ©2017 Richard L Halterman Draft date: November 30, 2017 655 Index needs a relationship, 514 absolute value, 102 accessor methods, 467 accumulator, 117 actual, 167 adapter design pattern, 539 adjacency list, 635 adjacent vertices, 631 aggregate, 514 aggregation, 514 algorithm, 63 aliases, 188 aliasing, 354 aliasing, object, 334 arc, 631 ascending ordering of list elements, 567 associative array, 402 associative container, 398 attributes, 312 base case, 244 base class, 519 benchmarking, 190 BFS, 637 binary search, 584 block, 12 body, 72 Boolean, 69 breadth-first search, 637 buffering, 252 bugs, 59 callback function, 253, 469 calling code, 159 catch-all exception handler, 433, 446 catching an exception, 429 chained assignment, 52 class, 17, 311 class constructor, 323 class hierarchy, 527 class variables, 507 ©2017 Richard L Halterman client, 312 client code, 159 closure, 275 code duplication, 223 code instrumentation, 604 comma-separated list, 21 command prompt, 368 commutative, 350 compiler, 2, composition, 513 concatenation, 18 conditional expression, 100 connected graph, 643 context manager, 318 control codes, 32 cooperative multiple inheritance, 541 cycle in a graph, 636 data, 311 data persistence, 316 debugger, decorator, 300 default argument, 238 default parameters, 238 definite loop, 121 delimit, 16 denominator, 323, 474 dependent function, 237 depth-first search, 647 derivative, 290 derived class, 519 design pattern, 539 DFS, 647 dictionary, 398 dictionary key, 398 differentiation, 290 digraph, 631 dir function, 165 direct base class, 525 directed graph, 631 directory function, 165 disconnected graph, 643 Draft date: November 30, 2017 656 INDEX docstring, 212 documentation string, 212 double negative, 79 double underscore, 473 dunder, 473 EAFP, 429 easier to ask for forgiveness than permission, 429 edge, 631 elapsed time, 171 end keyword argument in print, 36 Eratosthenes, 366 escape symbol, 32 except block, 429 exception, 425 exception else block, 451 exception classes, common standard, 426 exception handling, 425 exception, re-raising, 448 exception, swallowing, 446 existential quantification, 417 expression, 15 external documentation, 212 factorial, 241 Fibonacci sequence, 245 fields, 312 files, 316 finally block, 453 floating-point numbers, 28 for statement, 122 formal, 167 formatting string, 39 function, 158 function definition, 194 function invocation, 194 function time.clock, 170 function time.sleep, 172 function call, 159 function coherence, 214 function composition, 207, 219 function definition parts, 194 function invocation, 159 functional composition, 34 functional decomposition, 194 functional independence, 237 functionally equivalent, 568 garbage, 336 garbage collection, 336 generalized unpacking, 396 ©2017 Richard L Halterman generator, 280 generator comprehension, 374 generator expression, 374 get attribute, 505 getattr, 505 getters, 467 global variable, 233 graph, 631 graph theory, 631 handling an exception, 429 has a relationship, 514 hash tables, 402 hashing, 402 Hoare, C A R., 582 id function, 165 identifier, 26 identifiers beginning with two underscores, 473 if statement, 71 immutable, 209 in place list processing, 596 indefinite loop, 122 index, 315, 341 indirect base class, 525 inheritance, 518 inheritance hierarchy, 527 inheritance, single, 519 instance variable, 312 instance variable, object, 463 integer division, 46 internal documentation, 212 interpreter, 3, is a, 524 key, 398, 399 keyword argument, 36 keyword arguments, 411 keywords, 27 lambda calculus, 274 lambda expression, 274 last-in, first out, 647 lazy list, 385 LBYL, 428 LCS, 621 len function, 345 length, 345 LIFO, 647 linear search, 584 list aliasing, 354 Draft date: November 30, 2017 657 INDEX list comprehension, 370 list function, 348 list of lists, 375 list slicing, 358 local variables, 233 longest common subsequence, 621 look before you leap, 428 loop unrolling, 601 mathematical graph, 631 matrix, 375 member, object, 463 members, 312 memoization, 617 Mersenne Twister, 173 method call, 312 method resolution order, 547 method, object, 463 methods, 311 midpoint, 200 module, 159, 162 modules, 157, 248 modulus, 46 monolithic code, 193 MRO, 547 multiple inheritance, 540 multiplication table, 126 mutable, 344, 355 mutator methods, 467 name collision, 186 namespace, 186 namespace pollution, 187 nested, 84 nested loop, 126 newline, 32 node, 631 non-decreasing order of list elements, 567 None object reference, 336 numerator, 323, 474 numerical differentiation, 291 object aliasing, 334 object composition, 472 object oriented, 311 operations, 312 override, 519 Papert, Seymour, 179 partial application, 304 pass statement, 82 ©2017 Richard L Halterman permutation, 131, 600 positional parameters, 39 predicate, 69, 417 private object members, 473 profiler, pure function, 238 qualified name, 163 quantification, 415 queue, 637 Quicksort, 582 ragged array, 376 random access, 385 re-raising an exception, 448 read, eval, print loop, 16 recursive, 241 recursive case, 244 refactoring, 223 refactoring code, 223 reference counting, 336 regular expression, 429 relational operators, 70 remainder, 46 reserved words, 27 run-time errors, 56 run-time exceptions, 56 scripting languages, selection sort, 576 sep keyword argument in print, 37 sequence, 621 set attribute, 505 set comprehension, 415 setattr, 505 setters, 467 short-circuit evaluation, 81 Sieve of Eratosthenes, 366 single inheritance, 519 slice assignment, 360 slicing, 358 stack, 439, 647 stack trace, 439 stack unwinding, 439 statement, string, 16 string formatter, 40 stub, 497 subclass, 519 subscript, 341 subsequence, 621 Draft date: November 30, 2017 INDEX 658 super function, 519 superclass, 519 swallowing an exception, 446 symbolic differentiation, 291 syntactic sugar, 324 syntax error, 55 tab stop, 74 table, 376 tags, Tk, 514 terminal, 368 test runner, 562 test-driven development, 494 testing, 492 text files, 320 texttttry statement, 429 throw away variable, 381 throwing an exception, 429 times table, 126 Tk tags, 514 Tk toolkit, 326 tkinter, 326 token, 407 transitivity, 568 transitivity of class inhertiance, 525 translation phase, 55 try block, 429 tuple, 22 tuple assignment, 21 tuple unpacking, 201 Turtle graphics, 179 type, 17 UML, 527 unbound variable, 25 undefined variable, 25 underscore, beginning an identifier, 473 Unified Modeling Language, 527 unit testing, 558 universal quantification, 417 unpacking a tuple, 201 unwinding the stack, 439 value, 399 vertex, 631 while statement, 114 whitespace, 12 wrapper, 539 yield from, 606 yield statement, 281 ©2017 Richard L Halterman Draft date: November 30, 2017 ... http:/ /python. cs.southern.edu/pythonbook/pythonbook.pdf If you are an instructor using this book in one or more of your courses, please let me know Keeping track of how and where this book is... published books cover Python 2, but more Python resources now are becoming widely available The code in this book is based on Python This book does not attempt to cover all the facets of the Python. .. Commonly called Python 3, the current version of Python is incompatible with earlier versions of the language Currently the Python world still is in transition between Python and Python Many existing

Ngày đăng: 29/08/2022, 21:57

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w