How do use itertools in Python to build permutation or combination
5 stars based on
We now embark on a tour of the technology by which languages are established in terms of other languages. Metalinguistic abstraction — establishing new languages — plays an important role in all branches of engineering design.
It is particularly important to computer programming, because in programming not only can we formulate new languages but we can also implement these languages by constructing interpreters. An interpreter for a programming language is a function that, when applied to an expression of the language, performs the actions required to evaluate that expression. We will first define an interpreter for a language that is a limited subset of Scheme, called Calculator.
Then, we combination calculator python develop a sketch of an interpreter for Scheme as a whole. The interpreter we create will be complete in the sense that it will allow us to write fully general programs in Scheme. To do so, it will implement the same environment model of evaluation that combination calculator python introduced for Python programs in Chapter 1. Many of the examples in this section are contained in the companion Scheme-Syntax Calculator exampleas they are too complex to fit naturally in the format of this text.
The Scheme-Syntax Calculator or simply Calculator is an expression language for the arithmetic operations of addition, subtraction, multiplication, and division. Calculator shares Scheme's call expression syntax and operator behavior. Subtraction - has two behaviors. With one argument, it negates the argument. With at least two arguments, it subtracts all but the first from the first. A call expression is evaluated by evaluating its operand sub-expressions, then applying the operator to the resulting arguments:.
We will implement an interpreter for the Calculator combination calculator python in Python. That is, we will write a Python program that takes string lines as input and returns the result of combination calculator python those lines as a Calculator expression. Our interpreter will raise an appropriate exception if the calculator expression is not well formed. Until this point in the course, expression trees have been conceptual entities to which we have referred in describing the process of evaluation; we have never before explicitly represented expression trees as data in our programs.
In order to write an interpreter, we must operate on expressions as data. A primitive expression is just a number or a string in Calculator: All combined expressions are call expressions. A call expression is a Scheme list with a first element the operator followed by zero or more operand expressions. In Scheme, lists are nested pairs, but not all pairs are lists. To represent Scheme pairs and lists in Python, we will define a class Pair that is similar to the Rlist class earlier in the chapter.
The empty list is represented by an object called nil combination calculator python, which is an instance of the class nil. We assume that only one nil instance will ever be created. The Pair class and nil object are Scheme values represented in Python. They have repr strings that are Python expressions and str strings that are Scheme expressions.
They implement the basic Python sequence interface of length and element selection, as well as a map method that returns a Scheme list. Trees are represented in Scheme by allowing the elements of a Scheme list to be Scheme lists. Unlike the Tree class in the previous chapter, these expression trees have values only at the combination calculator python, and each tree can have any number of branches.
This example demonstrates that all Calculator expressions are nested Scheme lists. Our Calculator interpreter will read in nested Scheme lists, convert them into expression trees represented as nested Pair instances Parsing expressions belowand then evaluate the expression trees to combination calculator python values Calculator evaluation below. Parsing is the process of generating expression trees from raw text input.
A parser is a composition of two components: First, the lexical analyzer partitions the input string into tokenswhich are the minimal syntactic units of the language such as names and symbols. Second, the syntactic analyzer constructs an expression tree from this sequence of tokens. The sequence of tokens produced combination calculator python the lexical analyzer is consumed by combination calculator python syntactic analyzer.
The component that interprets a string as a token sequence is called a tokenizer or lexical analyzer. Scheme tokens combination calculator python delimited by white space, parentheses, dots, or single quotation marks. Delimiters are tokens, as are symbols and numerals. The tokenizer analyzes a line character by character, validating the format of symbols and numerals.
Tokenizing a well-formed Calculator expression separates all combination calculator python and delimiters, but identifies multi-character numbers e. Lexical analysis is an iterative process, and it can be applied to each line of an input program in isolation. The component that interprets a token sequence as an expression tree is called a syntactic analyzer. Syntactic analysis combination calculator python a tree-recursive process, and it must consider an entire expression that may span multiple lines.
It is tree-recursive because analyzing a sequence of tokens often involves analyzing a subsequence of those tokens into a subexpression, which itself serves as a branch e. Recursion generates the hierarchical structures consumed by the evaluator. A Bufferdefined in the buffer module, collects tokens that span multiple lines into a single object that can be analyzed syntactically. Its base cases are an empty input an error or a closing parenthesis that terminates the list.
Parsing dotted lists and quoted forms is combination calculator python as an exercise. Informative syntax errors improve the usability of an interpreter substantially. The SyntaxError exceptions that are raised include a description of the problem encountered.
The scalc module implements an evaluator for the Calculator language. For Calculator, the only two legal syntactic forms of expressions are numbers and call expressions, which are Pair instances representing well-formed Scheme lists. Call expressions require function application. The Calculator language is simple enough that we can easily express the logic of applying each operator in the body of a single function. Above, each suite computes the result of a different operator or raises an appropriate TypeError when the wrong number of arguments is given.
The first form of expression is a number, which requires no additional evaluation step. In general, primitive expressions that do not require an additional evaluation step are called self-evaluating.
Combination calculator python only self-evaluating expressions in our Calculator language are numbers, but a general programming language might also include strings, boolean values, etc. A typical approach to interacting with an interpreter is through a read-eval-print loop, or REPL, which is a mode of interaction that reads an expression, evaluates it, and prints the result for the user. Combination calculator python Python interactive session is an example of such a loop. An implementation of a REPL can be largely independent of the interpreter it uses.
Combination calculator python example session would look like:. This loop implementation has no mechanism for termination or error handling. We can improve combination calculator python interface by reporting errors to the user. To enable these improvements, we place the original suite of the while statement within a try statement.
This loop implementation reports errors without exiting the loop. Rather than exiting the program on an error, restarting the loop after an error message lets users revise their expressions. Upon importing the readline module, users can even recall their previous inputs using the up arrow or Control-P.
The final result provides an informative error reporting interface:. Beyond these changes, all REPLs can be implemented using the same structure. Chapter 3 Hide contents 3.