Đăng ký Đăng nhập

Tài liệu Functional python programming

.PDF
361
72
52

Mô tả:

Functional Python Programming Create succinct and expressive implementations with functional programming in Python Steven Lott BIRMINGHAM - MUMBAI Functional Python Programming Copyright © 2015 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. First published: January 2015 Production reference: 1270115 Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK. ISBN 978-1-78439-699-2 www.packtpub.com Credits Author Steven Lott Copy Editors Roshni Banerjee Pranjali Chury Reviewers Oleg Broytman Rui Carmo Ian Cordasco Julien Danjou Amoatey Harrison Deepa Nambiar Karuna Narayanan Nithya P Project Coordinator Danuta Jones Shivin Kapur Gong Yi Commissioning Editor Ed Gordon Acquisition Editor Owen Roberts Content Development Editor Sumeet Sawant Technical Editor Abhishek R. Kotian Proofreaders Stephen Copestake Maria Gould Bernadette Watkins Indexer Hemangini Bari Graphics Abhinash Sahu Production Coordinator Melwyn D'sa Cover Work Melwyn D'sa About the Author Steven Lott has been programming since the 1970s, when computers were large, expensive, and rare. As a contract software developer and architect, he has worked on hundreds of projects, from very small to very large. He's been using Python to solve business problems for over 10 years. He's particularly adept struggling with gnarly data representation problems. His other titles include Mastering Object-Oriented Python and Python for Secret Agents, both by Packt Publishing. After spending years as a technomad—living in various places on the east coast of the US—he has dropped the hook in the Chesapeake Bay. He blogs at http://slott-softwarearchitect. blogspot.com. About the Reviewers Oleg Broytman is a software developer currently working with web technologies on Unix/Linux using the Python programming language on the server side and Javascript on the client side. Oleg started to work with computers even before the IBM PC era. He worked with DOS for some time and then switched to Unix, mostly Linux and FreeBSD. For about 25 years, he has been working in the medicine field in Moscow, Russia. You can contact him at [email protected]. I'd like to thank my wife Olga! She supports everything I do any way I do it (well, mostly!). Her love and support make me happy and allow me to achieve as much as I do. Rui Carmo is a systems architect with 20 years' experience in telecoms and Internet, having worked in software development, product management, mobile network planning, systems engineering, virtualization, cloud services, and a lot of what the industry is currently trying to roll into the "DevOps" moniker. He has been coding in Python for over a decade (starting with Python 2.3) and has gravitated towards Clojure, Erlang, and Hy (an LISP that leverages the Python AST) in the past few years due to the intrinsic advantages of functional programming. He currently lives in the wonderful city of Lisbon, Portugal, with his wife and two children, and he blogs at http://taoofmac.com. You can find him on GitHub, Twitter, and Hacker News as @rcarmo. Julien Danjou is an open source hacker working at Red Hat. He started his career as a Debian developer and contributed to a lot of free software (GNU Emacs, Freedesktop, and so on), writing some software on his own, such as the awesome window manager. Nowadays, Julien contributes to OpenStack, an open source cloud platform entirely written in Python. He has been a Python developer since then, worked on Hy (an LISP dialect in Python), and written a self-published book titled The Hacker's Guide to Python in 2014. Amoatey Harrison is a Python programmer with a passion for building software systems to solve problems. When he is not programming, he is playing video games, swimming, or simply hanging out with friends. After graduating from the Kwame Nkrumah University of Science and Technology with a degree in computer engineering, he is doing his national service at the GCB Bank Head Office in Accra, Ghana. He would like to think of himself as a cool nerd. Shivin Kapur is an aspiring computer science student who is passionate about learning new things. Gong Yi is a software developer working in Shanghai, China. He maintains an open source project at https://github.com/topikachu/python-ev3, which can control LEGO® MINDSTORMS® EV3 by Python language. I thank my wife Zhu Xiaoling for her patience and love, and I thank my son Yang Yang for being the best thing ever. www.PacktPub.com Support files, eBooks, discount offers, and more For support files and downloads related to your book, please visit www.PacktPub.com. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks. https://www2.packtpub.com/books/subscription/packtlib Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can search, access, and read Packt's entire library of books. Why subscribe? • Fully searchable across every book published by Packt • Copy and paste, print, and bookmark content • On demand and accessible via a web browser Free access for Packt account holders If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view 9 entirely free books. Simply use your login credentials for immediate access. Table of Contents Preface 1 Chapter 1: Introducing Functional Programming 9 Identifying a paradigm 10 Subdividing the procedural paradigm 11 Using the functional paradigm 12 Using a functional hybrid 14 Looking at object creation 15 The stack of turtles 16 A classic example of functional programming 17 Exploratory Data Analysis 20 Summary 22 Chapter 2: Introducing Some Functional Features 23 Chapter 3: Functions, Iterators, and Generators 37 First-class functions 24 Pure functions 24 Higher-order functions 25 Immutable data 26 Strict and non-strict evaluation 27 Recursion instead of a explicit loop state 29 Functional type systems 33 Familiar territory 34 Saving some advanced concepts 34 Summary 35 Writing pure functions Functions as first-class objects Using strings 38 39 41 Table of Contents Using tuples and namedtuples 42 Using generator expressions 43 Exploring the limitations of generators 46 Combining generator expressions 47 Cleaning raw data with generator functions 48 Using lists, dicts, and sets 50 Using stateful mappings 53 Using the bisect module to create a mapping 55 Using stateful sets 56 Summary 57 Chapter 4: Working with Collections 59 Chapter 5: Higher-order Functions 87 An overview of function varieties 60 Working with iterables 60 Parsing an XML file 61 Parsing a file at a higher level 63 Pairing up items from a sequence 65 Using the iter() function explicitly 67 Extending a simple loop 68 Applying generator expressions to scalar functions 71 Using any() and all() as reductions 73 Using len() and sum() 75 Using sums and counts for statistics 76 Using zip() to structure and flatten sequences 78 Unzipping a zipped sequence 80 Flattening sequences 80 Structuring flat sequences 81 Structuring flat sequences—an alternative approach 83 Using reversed() to change the order 84 Using enumerate() to include a sequence number 85 Summary 86 Using max() and min() to find extrema Using Python lambda forms Lambdas and the lambda calculus Using the map() function to apply a function to a collection Working with lambda forms and map() Using map() with multiple sequences Using the filter() function to pass or reject data Using filter() to identify outliers The iter() function with a sentinel value [ ii ] 88 91 93 93 94 95 96 98 99 Table of Contents Using sorted() to put data in order 100 Writing higher-order functions 101 Writing higher-order mappings and filters 101 Unwrapping data while mapping 103 Wrapping additional data while mapping 104 Flattening data while mapping 106 Structuring data while filtering 107 Writing generator functions 108 Building higher-order functions with Callables 111 Assuring good functional design 112 Looking at some of the design patterns 114 Summary 116 Chapter 6: Recursions and Reductions Simple numerical recursions Implementing tail-call optimization Leaving recursion in place Handling difficult tail-call optimization Processing collections via recursion Tail-call optimization for collections Reductions and folding – from many to one Group-by reductions – from many to fewer Building a mapping with Counter Building a mapping by sorting Grouping or partitioning data by key values Writing more general group-by reductions Writing higher-order reductions Writing file parsers Parsing CSV files Parsing plain text files with headers 117 118 119 120 121 122 123 124 126 127 128 130 132 133 135 137 138 Summary 140 Chapter 7: Additional Tuple Techniques 141 Using an immutable namedtuple as a record 142 Building namedtuples with functional constructors 145 Avoiding stateful classes by using families of tuples 145 Assigning statistical ranks 148 Wrapping instead of state changing 149 Rewrapping instead of state changing 150 Computing the Spearman rank-order correlation 152 Polymorphism and Pythonic pattern matching 153 Summary 158 [ iii ] Table of Contents Chapter 8: The Itertools Module 159 Chapter 9: More Itertools Techniques 181 Chapter 10: The Functools Module 197 Working with the infinite iterators 160 Counting with count() 160 Reiterating a cycle with cycle() 162 Repeating a single value with repeat() 164 Using the finite iterators 165 Assigning numbers with enumerate() 166 Running totals with accumulate() 167 Combining iterators with chain() 169 Partitioning an iterator with groupby() 170 Merging iterables with zip_longest() and zip() 171 Filtering with compress() 171 Picking subsets with islice() 172 Stateful filtering with dropwhile() and takewhile() 173 Two approaches to filtering with filterfalse() and filter() 175 Applying a function to data via starmap() and map() 176 Cloning iterators with tee() 177 The itertools recipes 178 Summary 179 Enumerating the Cartesian product 182 Reducing a product 182 Computing distances 184 Getting all pixels and all colors 185 Performance analysis 186 Rearranging the problem 188 Combining two transformations 189 Permuting a collection of values 190 Generating all combinations 191 Recipes 194 Summary 195 Function tools Memoizing previous results with lru_cache Defining classes with total ordering Defining number classes Applying partial arguments with partial() Reducing sets of data with reduce() Combining map() and reduce() Using reduce() and partial() [ iv ] 198 198 201 203 205 206 207 208 Table of Contents Using map() and reduce() to sanitize raw data 209 Using groupby() and reduce() 210 Summary 212 Chapter 11: Decorator Design Techniques 213 Chapter 12: The Multiprocessing and Threading Modules 229 Chapter 13: Conditional Expressions and the Operator Module 253 Decorators as higher-order functions 213 Using functool's update_wrapper() functions 216 Cross-cutting concerns 217 Composite design 218 Preprocessing bad data 219 Adding a parameter to a decorator 220 Implementing more complex descriptors 223 Recognizing design limitations 223 Summary 227 What concurrency really means 230 The boundary conditions 231 Sharing resources with process or threads 231 Where benefits will accrue 232 Using multiprocessing pools and tasks 233 Processing many large files 234 Parsing log files – gathering the rows 235 Parsing log lines into namedtuples 236 Parsing additional fields of an Access object 238 Filtering the access details 241 Analyzing the access details 243 The complete analysis process 244 Using a multiprocessing pool for concurrent processing 244 Using apply() to make a single request 247 Using map_async(), starmap_async(), and apply_async() 247 More complex multiprocessing architectures 248 Using the concurrent.futures module 248 Using concurrent.futures thread pools 249 Using the threading and queue modules 250 Designing concurrent processing 250 Summary 252 Evaluating conditional expressions Exploiting non-strict dictionary rules Filtering true conditional expressions [v] 254 255 256 Table of Contents Using the operator module instead of lambdas 256 Getting named attributes when using higher-order functions 257 Starmapping with operators 258 Reducing with operators 260 Summary 261 Chapter 14: The PyMonad Library 263 Chapter 15: A Functional Approach to Web Services 281 Downloading and installing 263 Functional composition and currying 264 Using curried higher-order functions 266 Currying the hard way 268 Functional composition and the PyMonad multiplication operator 268 Functors and applicative functors 270 Using the lazy List() functor 271 Monad concepts, the bind() function and the Binary Right Shift operator 274 Implementing simulation with monads 275 Additional PyMonad features 279 Summary 280 The HTTP request-response model 282 Injecting a state via cookies 284 Considering a server with a functional design 284 Looking more deeply into the functional view 285 Nesting the services 286 The WSGI standard 287 Throwing exceptions during WSGI processing 288 Pragmatic WSGI applications 290 Defining web services as functions 291 Creating the WSGI application 292 Getting raw data 294 Applying a filter 295 Serializing the results 296 Serializing data into the JSON or CSV format 298 Serializing data into XML 299 Serializing data into HTML 300 Tracking usage 301 Summary 303 [ vi ] Table of Contents Chapter 16: Optimizations and Improvements 305 Memoization and caching 305 Specializing memoization 307 Optimizing storage 311 Optimizing accuracy 311 Reducing accuracy based on audience requirements 312 Case study – making a chi-squared decision 312 Filtering and reducing the raw data with a Counter object 314 Reading summarized data 316 Computing probabilities from a Counter object 317 Alternative summary approaches 318 Computing expected values and displaying a contingency table 319 Computing the chi-squared value 321 Computing the chi-squared threshold 322 Computing the partial gamma value 323 Computing the complete gamma value 325 Computing the odds of a distribution being random 327 Summary 329 Index 331 [ vii ] Preface Programming languages sometimes fit neatly into tidy categories like imperative and functional. Imperative languages might further subdivide into those that are procedural and those that include features for object-oriented programming. The Python language, however, contains aspects of all of these three language categories. Though Python is not a purely functional programming language, we can do a great deal of functional programming in Python. Most importantly, we can leverage many design patterns and techniques from other functional languages and apply them to Python programming. These borrowed concepts can lead us to create succinct and elegant programs. Python's generator expressions, in particular, avoid the need to create large in-memory data structures, leading to programs which may execute more quickly because they use fewer resources. We can't easily create purely functional programs in Python. Python lacks a number of features that would be required for this. For example, we don't have unlimited recursion, lazy evaluation of all expressions, and an optimizing compiler. Generally, Python emphasizes strict evaluation rules. This means that statements are executed in order and expressions are evaluated from left to right. While this deviates from functional purity, it allows us to perform manual optimizations when writing in Python. We'll take a hybrid approach to functional programming using Python's functional features when they can add clarity or simplify the code and use ordinary imperative features for optimization. There are several key features of functional programming languages that are available in Python. One of the most important is the idea that functions are first-class objects. In some languages, functions exist only as a source code construct: they don't exist as proper data structures at runtime. In Python, functions can use functions as arguments and return functions as results. Preface Python offers a number of higher-order functions. Functions like map(), filter(), and functools.reduce() are widely used in this role. Less obvious functions like sorted(), min(), and max() are also higher-order functions; they have a default function and, consequently, different syntax from the more common examples. Functional programs often exploit immutable data structures. The emphasis on stateless objects permits flexible optimization. Python offers tuples and namedtuples as complex but immutable objects. We can leverage these structures to adapt some design practices from other functional programming languages. Many functional languages emphasize recursion but exploit Tail-Call Optimization (TCO). Python tends to limit recursion to a relatively small number of stack frames. In many cases, we can think of a recursion as a generator function. We can then simply rewrite it to use a yield from statement, doing the tail-call optimization ourselves. We'll look at the core features of functional programming from a Python point of view. Our objective is to borrow good ideas from functional programming languages, and use these ideas to create expressive and succinct applications in Python. What this book covers Chapter 1, Introducing Functional Programming, introduces some of the techniques that characterize functional programming. We'll identify some of the ways to map these features to Python, and finally, we'll also address some ways that the benefits of functional programming accrue when we use these design patterns to build Python applications. Chapter 2, Introducing Some Functional Features, will delve into six central features of the functional programming paradigm. We'll look at each in some detail to see how they're implemented in Python. We'll also point out some features of functional languages that don't apply well to Python. In particular, many functional languages have complex type-matching rules required to support compilation and optimization. Chapter 3, Functions, Iterators, and Generators, will show how to leverage immutable Python objects and generator expressions, and adapt functional programming concepts to the Python language. We'll look at some of the built-in Python collection and how we can leverage them without departing too far from functional programming concepts. Chapter 4, Working with Collections, shows how we can use a number of built-in Python functions to operate on collections of data. This section will focus on a number of relatively simple functions such as any() and all(), which will reduce a collection of values to a single result. [2] Preface Chapter 5, Higher-order Functions, examines the commonly used higher order functions such as map() and filter(). The chapter also includes a number of other functions that are also higher-order functions, as well as how we can create our own higher-order functions. Chapter 6, Recursions and Reductions, shows how we can design an algorithm using recursion and then optimize it into a high performance for loop. We'll also look at some other reductions that are widely used, including the collections.Counter() function. Chapter 7, Additional Tuple Techniques, shows a number of ways in which we can use immutable tuples and namedtuples instead of stateful objects. Immutable objects have a much simpler interface: we never have to worry about abusing an attribute and setting an object into some inconsistent or invalid state. Chapter 8, The Itertools Module, examines a number of functions in the standard library module. This collection of functions simplifies writing programs that deal with collections or generator functions. Chapter 9, More Itertools Techniques, covers the combinatoric functions in the itertools module. These functions are somewhat less useful. This chapter includes some examples that illustrate ill-considered uses of these functions and the consequences of combinatoric explosion. Chapter 10, The Functools Module, will show how to use some of the functions in this module for functional programming. A few of the functions in this module are more appropriate for building decorators, and are left for the next chapter. The other functions, however, provide several more ways to design and implement function programs. Chapter 11, Decorator Design Techniques, shows how we can look at a decorator as a way to build a composite function. While there is considerable flexibility here, there are also some conceptual limitations: we'll look at ways in which overly complex decorators can become confusing rather than helpful. Chapter 12, The Multiprocessing and Threading Modules, points out an important consequence of good functional design: we can distribute the processing workload. Using immutable objects means that we can't corrupt an object because of poorly synchronized write operations. Chapter 13, Conditional Expressions and the Operator Module, will show some ways in which we can break out of Python's strict order of evaluation. There are limitations to what we can achieve here. We'll also look at the operator module and how the operator module can lead to some slight clarification of some simple kinds of processing. [3]
- Xem thêm -

Tài liệu liên quan