text:
# Contributing to eslint-config-skyscanner

We're glad you want to make a contribution!

_For Skyscanner employees_

If you are a Skyscanner employee, please follow the "Engineering Contribution" guide in the Backpack space in Confluence to get push rights to this repository.

_For non employees_

Fork this repository and send in a pull request when you're finished with your changes. Link any relevant issues in too.

Take note of the build status of your pull request, only builds that pass will be accepted. Please also keep to our conventions and style so we can keep this repository as clean as possible.

## Pre-commit hooks

This project contains some pre-commit hooks that will format automatically some files based on our guidelines.

When performing a commit, the modified files will be formatted and added to the commit. In case of not been able to fix any of the issues, the commit will be aborted the list of errors will be displayed in the console.

One of the steps is running a spellchecker for the markdown files. In case of some word requiring an exception, add it to [.spelling](.spelling) file.

## License

By contributing your code, you agree to license your contribution under the terms of the APLv2: [LICENSE](LICENSE.md)

All files are released with the Apache 2.0 license.

If you are adding a new file it should have a header like this:

```
/*
 Copyright 2021 Skyscanner
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
```

repository: Skyscanner/eslint-config-skyscanner

gha_license_id: NOASSERTION

repo_name: Skyscanner/eslint-config-skyscanner


text:
# Example Swagger Example REST API Parent Project

Example project, which uses Swagger, Xtend, some Maven plugins and 'mvn generate-sources site' to generate REST Projects (Java REST API, Java REST client, Android REST client and iOS client) and documentation (REST API Doc, JavaDoc, Maven Site, DocBook, PDF etc.) from YAML.

## Usage

* Define your REST API: /rest-generate/yaml/api.yaml
* Build projects including documentation:

	mvn install site
* Run generated WAR (/swagger-example-api/target/swagger-example-api.war) on Server (JBoss, Tomcat, Jetty etc.)
* Have a look at generated API documentation: http://localhost:8080/example/index.html
* Develop against your REST API: http://localhost:8080/example/rest/somethings
* Run and test your REST API in Docker image:

	mvn install -Pdocker

repository: thlaegler/swagger-example

branch_name: refs/heads/master

extension: md

gha_language: HTML

license_type: permissive

repo_name: thlaegler/swagger-example


text:
##Description:

Log separation is indispensable in order to prevent it from either radically downgrading your
application its performance or even causing a Denial of service because the server becomes
unavailable due to the flooding of logs.

##Mitigation:

Log rotation is an automated process used in system administration in which dated log
files are archived. Servers which run large applications, such as LAMP stacks, often
log every request: in the face of bulky logs, log rotation is a way to limit the total
size of the logs while still allowing analysis of recent events.

Log separation basically means that you have to store your log files on a different partition
as where your OS/application is running on in order to avert a Denial of service attack or the downgrading
of your application its performance.

branch_name: refs/heads/main


text:
# Chapter 5. First-class functions
*I have never considered Python to be heavily influenced by functional languages, no matter what people say or think. I was much more familiar with imperative languages such as C and Algol 68 and although I had made functions first-class objects, I didn’t view Python as a functional programming language[43].
— Guido van Rossum Python BDFL*

Functions in Python are first-class objects. Programming language theorists define a “first-class object” as a program entity that can be:

Python中的函数是一级对象。编程语言专家定义“一级对象”作为程序实体时具有以下特点：

-   created at runtime;
-   assigned to a variable or element in a data structure;
-   passed as an argument to a function;
-   returned as the result of a function.

- 在运行时创建；
- 在一个数据结构中变量或者元素；
- 作为参数传递到一个函数；
- 作为函数的结果被返回；

Integers, strings and dictionaries are other examples of first-class objects in Python—nothing fancy here. But, if you came to Python from a language where functions are not first-class citizens, this chapter and the rest of Part III of the book focuses on the implications and practical applications of treating functions as objects.

这里整数、字符串和字典以及Python中其他一级对象的例子都没什么特别的。但是，如果你

>#### TIP 提示
>The term “first-class functions” is widely used as shorthand for “functions as first class objects”. It’s not perfect because it seems to imply an “elite” among functions. In Python, all functions are first-class.

>术语“一级函数”被广泛用作“函数即一级对象”的简写。这样的说法并不完美，因为它。在Python中，所有的函数都是一级对象。

## Treating a function like an object 把函数看作对象
The following console session shows that Python functions are objects. Here we create a function, call it, read its `__doc__` attribute, and check that the function object itself is an instance of the function class:

下面的终端绘画显示了Python函数就是对象。这里我们创建了一个函数，然后调用它，以读取它的`__doc__`属性，然后

*Example 5-1. Create and test a function, then read its `__doc__` and check its type.*
例子 5-1。创建并测试一个函数，然后读区它的`__doc__`，再检查其类型。

```python
>>> def factorial(n):     # 1
...     '''returns n!'''
...     return 1 if n < 2 else n * factorial(n-1)
...
>>> factorial(42)
1405006117752879898543142606244511569936384000000000
>>> factorial.__doc__     # 2
'returns n!'
>>> type(factorial)       # 3
<class 'function'>
```

1. This is a console session, so we’re creating a function in “run time”.
2. `__doc__` is one of several attributes of function objects.
3. factorial is an instance of the function class.

1. 因为这是一个终端会话，所以我们是在“运行时”创建一个函数。
2. `__doc__`是函数对象多个属性的其中一个。
3. factorial是function类的实例。

The `__doc__` attribute is used to generate the help text of an object. In the Python interactive console, the command help(factorial) will display a screen like that in Figure 5-1:

`__doc__`属性用来生成一个对象的注释文本。在Python的交互控制台中，命令help(factorial)显示的屏幕结果会和图5－1中的一样：

Figure 5-1. Help screen for the factorial function. The text is from the `__doc__` attribute of the function object.
图5-1. factorial函数的屏幕结果。文本来自函数对象的`__doc__`属性。

The next snippet shows the “first class” nature of a function object. We can assign it a variable fact and call it through that name. We can also pass factorial as an argument to map. The map function returns an iterable where each item is the the result of the application of the first argument (a function) to succesive elements of the second argument (an iterable), range(10) in this example.

接下来的代码片段展示了函数对象“一级对象”本性。我们还可以将factorial作为参数传递到map。map函数返回一个可迭代对象，其中每个项都是第一个参数（函数）第二个连续参数（可迭代对象，本例中为range(10)）的结果。

*Example 5-2. Use function through a different name, and pass function as argument.*

例子5-2. 通过不同的名称调用函数，并把函数作为参数进行传递。

```python
>>> fact = factorial
>>> fact
<function factorial at 0x...>
>>> fact(5)
120
>>> map(factorial, range(11))
<map object at 0x...>
>>> list(map(fact, range(11)))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
```

Having first-class functions enables programming in a functional style. One of the hallmarks of functional programming is the use of higher-order functions, our next topic.

利用以及函数能够编进行函数化风格编程。函数化编程的一个标志性用法是高阶函数，这也正是我们接下来要谈到议题。

## Higher-order functions 高阶函数
A function that takes a function as argument or returns a function as result is a higher-order function. One example is map, shown in Example 5-2. Another is the sorted built-in function: an optional key argument lets you provide a function to be applied to each item for sorting, as seen in list.sort and the sorted built-in function.

高阶函数是一个把函数作为参数，或者把函数作为返回结果的函数。其中一个例子是例子5-2中的map。另外一个是内建函数sorted：可选的参数key可以让你在排序时将提供函数应用到每个项，一如在list.sort和内建函数sorted中所见的那样。

For example, to sort a list of words by length, simply pass the len function as the key, as in Example 5-3.

例如，按单词长度排序一个列表，简单的把len函数作为键传递即可，一如例子5-3所示。

*Example 5-3. Sorting a list of words by length.*

例子5-3. 按照长度排列单词列表。

```python
>>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
>>> sorted(fruits, key=len)
['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
```

Any one-argument function can be used as key. For example, to create a rhyme dictionary it might be useful to sort each word spelled backwards. In the next snippet, note that the words in the list are not changed at all, only their reversed spelling is used as the sort criterion, so that the berries appear together.

任何的单参数函数都可用作key。例如，要创建一个押韵的字典，向后排列每个单词的拼写就显得非常有用。在接下来的代码片段中，列表中的单词根本没有被改变，只有它们的逆序拼写作为排序标准，所以浆果们都排在了一起。

*Example 5-4. Sorting a list of words by their reversed spelling.*

例子5-4. 根据逆序拼写排列一个单词列表。

```python
>>> def reverse(word):
...     return word[::-1]
>>> reverse('testing')
'gnitset'
>>> sorted(fruits, key=reverse)
['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
```

In the functional programming paradigm, some of the best known higher-order functions are map, filter, reduce and apply. The apply function was deprecated in Python 2.3 and removed in Python 3 because it’s no longer necessary. If you need to call a function with a dynamic set of arguments, you can just write fn(`*args`, `**keywords`) instead of apply(fn, args, kwargs).

在函数化编程范式中，一些最常见的高阶函数有map，filter，reduce和apply。apply函数在Python2.3时被丢弃，在Python 3 时被删除，因为没有使用的必要了。如果你需要调用一个函数

The map, filter and reduce higher-order functions are still around, but better alternatives are available for most of their use cases, as the next section shows.

## Modern replacements for map, filter and reduce
Functional languages commonly offer the map, filter and reduce higher-order functions (sometimes with different names). The map and filter functions are still built-ins in Python 3, but since the introduction of list comprehensions and generator expressions, they are not as important. A listcomp or a genexp does the job of map and filter combined, but is more readable. Consider this:

函数化语言通常提供map，filter和reduce高阶函数（有时使用另外的名称）。map和filter函数在Python 3 中仍旧是内建的，但是自从列表解析式和生成器表达式的引入，它们已显得不再重要了。列表

*Example 5-5. Lists of factorials produced with map and filter compared to alternatives coded as list comprehensions.*

例子5.5。

```python
>>> list(map(fact, range(6)))
[1, 1, 2, 6, 24, 120]
>>> [fact(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
>>> list(map(factorial, filter(lambda n: n % 2, range(6))))
[1, 6, 120]
>>> [factorial(n) for n in range(6) if n % 2]
[1, 6, 120]
```

Build a list of factorials from 0! to 5!

Same operation, with a list comprehension.

List of factorials of odd numbers up to 5!, using both map and filter.

List comprehension does the same job, replacing map and filter, and making lambda unnecessary.

In Python 3, map and filter return generators—a form of iterator—so their direct substitute is now a generator expression (in Python 2 these functions returned lists, therefore their closest alternative is a listcomp).

在Python 3中，map和filter返回

The reduce function was demoted from a built-in in Python 2 to the functools module in Python 3. Its most common use case, summation, is better served by the sum built-in available since Python 2.3 was released in 2003. This is a big win in terms of readability and performance (see Example 5-5).

reduce函数在Python2中的内建函数中降级到了Python 3中的functools模块。最常见的用法求和，

*Example 5-6. Sum of integers up to 99 performed with reduce and sum.*

例子5-6. 使用reduce和sum之行整数加到99的总和。

```python
>>> from functools import reduce
>>> from operator import add
>>> reduce(add, range(100))
4950
>>> sum(range(100))
4950
```

Starting with Python 3.0, reduce is not a built-in.

从Python 3.0开始，reduce不再内建。

Import add to avoid creating a function just to add two numbers.
Sum integers up to 99.
Same task using sum; import or adding function not needed.

The common idea of sum and reduce is to apply some operation to successive items in a sequence, accumulating previous results, thus reducing a sequence of values to a single value.

Other reducing built-ins are all and any:

all(iterable)
return True if every element of the iterable is truthy; all([]) returns True.

any(iterable)
return True if any element of the iterable is truthy; all([]) returns False.

I give a fuller explanation of reduce in Vector take #4: hashing and a faster == where an ongoing example provides a meaningful context for the use of this function. The reducing functions are summarized later in the book when iterables are in focus, in Iterable reducing functions.

To use a higher-order function sometimes it is convenient to create a small, one-off function. That is why anonymous functions exist. We’ll cover them next.

## Anonymous functions 匿名函数
The lambda keyword creates an anonymous function within a Python expression.
However, the simple syntax of Python limits the body of lambda functions to be pure expressions. In other words, the body of a lambda cannot make assignments or use any other Python statement such as while, try etc.

lambda关键字可以创建位于Python表达式内部的匿名函数。
不过，由于Python的简单与法限制了lambda函数的主体成为纯表达式的可能。换句话说，

The best use of anonymous functions is in the context of an argument list. For example, here is the rhyme index example from Example 5-4 rewritten with lambda, without defining a reverse function:

匿名函数的最佳用法是在一个参数列表的上下文中。例如，下面是来自例子5-4的使用了lambda重写，而不用定义reverse函数的押韵索引示例：

*Example 5-7. Sorting a list of words by their reversed spelling using lambda.*

```python
>>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
>>> sorted(fruits, key=lambda word: word[::-1])
['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
```

Outside the limited context of arguments to higher-order functions, anonymous functions are rarely useful in Python. The syntactic restrictions tend to make non-trivial lambdas either unreadable or unworkable.

>#### LUNDH’S LAMBDA REFACTORING RECIPE
>If you find a piece of code hard to understand because of a lambda, Fredrik Lundh suggests this refactoring procedure:

>1   Write a comment explaining what the heck that lambda does.
>2   Study the comment for a while, and think of a name that captures the essence of the comment.
>3   Convert the lambda to a def statement, using that name.
>4   Remove the comment.

>The steps above are quoted from the Functional Programming HOWTO, a must read.

The `lambda` syntax is just syntactic sugar: a `lambda` expression creates a function object just like the def statement. That is just one of several kinds of callable objects in Python. The following section overviews all of them.

`lambda`只是语法糖而已：`lambda`表达式和def语句一样能够创建一个函数对象。而且创建这个对象也只是Python中可调用对象的其中一种。下面一节概览了全部的可调用对象类型。

## The seven flavors of callable objects
## 7种风格的可调用对象
The call operator, i.e. (), may be applied to other objects beyond user-defined functions. To determine whether an object is callable, use the callable() built-in function. The Python Data Model documentation lists seven callable types:

*User-defined functions*
created with def statements or lambda expressions.

*Built-in functions*
a function implemented in C (for CPython), like len or time.strftime.

*Built-in methods*
methods implemented in C, like dict.get.

*Methods*
functions defined in the body of a class.

*Classes*
when invoked, a class runs its __new__ method to create an instance, then __init__ to initialize it, and finally the instance is returned to the caller. Because there is no new operator in Python, calling a class is like calling a function[44].

*Class instances*
if a class defines a __call__ method, then its instances may be invoked as functions. See User defined callable types below.

*Generator functions*
functions or methods that use the yield keyword. When called, generator functions return a generator object.

Generator functions are unlike other callables in many respects. Chapter 14 is devoted to them. They can also be used as coroutines, which are covered in Chapter 16.

>#### TIP
Given the variety of existing callable types in Python, the safest way to determine whether an object is callable is to use the callable() built-in:

```python
>>> abs, str, 13
(<built-in function abs>, <class 'str'>, 13)
>>> [callable(obj) for obj in (abs, str, 13)]
[True, True, False]
```

We now move to building class instances that work as callable objects.

## User defined callable types  用户定义可调用类型
Not only are Python functions real objects, but arbitrary Python objects may also be made to behave like functions. Implementing a `__call__` instance method is all it takes.

Example 5-8 implements a BingoCage class. An instance is built from any iterable, and stores an internal list of items, in random order. Calling the instance pops an item.

*Example 5-8. bingocall.py: A BingoCage does one thing: picks items from a shuffled list.*

```python
import random

class BingoCage:

    def __init__(self, items):
        self._items = list(items)
        random.shuffle(self._items)
    def pick(self):
          try:
            return self._items.pop()
        except IndexError:
            raise LookupError('pick from empty BingoCage')
     def __call__(self):
           return self.pick()
 ```

`__init__` accepts any iterable; building a local copy prevents unexpected side-effects on any list passed as an argument.

shuffle is guaranteed to work because self._items is a list.

The main method.

Raise exception with custom message if self._items is empty.

Shortcut to bingo.pick(): bingo().

Here is a simple demo of Example 5-8. Note how a bingo instance can be invoked as a function, and the callable(…) built-in recognizes it as a callable object.

```python
>>> bingo = BingoCage(range(3))
>>> bingo.pick()
1
>>> bingo()
0
>>> callable(bingo)
True
```

A class implementing `__call__` is an easy way to create function-like objects that have some internal state that must be kept across invocations, like the remaining items in the BingoCage. An example is a decorator. Decorators must be functions, but it is sometimes convenient to be able to “remember” something between calls of the decorator, for example for memoization—caching the results of expensive computations for later use.

A totally different approach to creating functions with internal state is to use closures. Closures, as well as decorators, are the subject of Chapter 7.

We now move to another aspect of handling functions as objects: run-time introspection.

## Function introspection
## 函数内省
Function objects have many attributes beyond `__doc__`. See below what the dir function reveals about our factorial:

函数对象拥有除了`__doc__`之外的很多属性。

```python
>>> dir(factorial)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__',
'__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__',
'__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__']
```

Most of these attributes are common to Python objects in general. In this section we cover those which are especially relevant to treating functions as objects, starting with `__dict__`.

Like the instances of a plain user-defined class, a function uses the `__dict__` attribute to store user attributes assigned to it. This is useful as a primitive form of annotation. Assigning arbitrary attributes to functions is not a very common practice in general, but Django is one framework that uses it. See, for example, the short_description, boolean and allow_tags attributes described in The Django admin site documentation. In the Django docs this example shows attaching a short_description to a method, to determine the description that will appear in record listings in the Django admin when that method is used:

```python
    def upper_case_name(obj):
        return ("%s %s" % (obj.first_name, obj.last_name)).upper()
    upper_case_name.short_description = 'Customer name'
```

Now let us focus on the attributes that are specific to functions and are not found in a generic Python user-defined object. Computing the difference of two sets quickly gives us a list of the function-specific attributes:

*Example 5-9. Listing attributes of functions that don’t exist in plain instances.*

```python
>>> class C: pass  #
>>> obj = C()  #
>>> def func(): pass  #
>>> sorted(set(dir(func)) - set(dir(obj))) #
['__annotations__', '__call__', '__closure__', '__code__', '__defaults__',
'__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__']
```

Create bare user-defined class.

Make an instance of it.

Create a bare function.

Using set difference, generate a sorted list of the attributes that exist in a function but not in an instance of a bare class.

Table 5-1 shows a summary of the attributes listed by Example 5-9.

*Table 5-1. Attributes of user-defined functions*

name    type    description
__annotations__ dict    parameter and return annotations
__call__    method-wrapper  implementation of the () operator; a.k.a. the callable object protocol
__closure__ tuple   the function closure, i.e. bindings for free variables (often is None)
__code__    code    function metadata and function body compiled into bytecode
__defaults__    tuple   default values for the formal parameters
__get__ method-wrapper  implementation of the read-only descriptor protocol (see XREF)
__globals__ dict    global variables of the module where the function is defined
__kwdefaults__  dict    default values for the keyword-only formal parameters
__name__    str the function name
__qualname__    str the qualified function name, ex.: Random.choice (see PEP-3155)

In coming sections we will discuss the `__defaults__`, `__code__` and `__annotations__`, used by IDEs and frameworks to extract information about function signatures. But to fully appreciate these attributes, we will make a detour to explore the powerful syntax Python offers to declare function parameters and to pass arguments into them.

## From positional to keyword-only parameters
## 位置参数与关键字参数
One of the best features of Python functions is the extremely flexible parameter handling mechanism, enhanced with keyword-only arguments in Python 3. Closely related are the use of * and ** to “explode” iterables and mappings into separate arguments when we call a function. To see these features in action, see the code for Example 5-10 and tests showing its use in Example 5-11.

*Example 5-10. tag generates HTML. A keyword-only argument cls is used to pass "class" attributes as a work-around because class is a keyword in Python.*

```python
def tag(name, *content, cls=None, **attrs):
    """Generate one or more HTML tags"""
    if cls is not None:
        attrs['class'] = cls
    if attrs:
        attr_str = ''.join(' %s="%s"' % (attr, value)
                           for attr, value
                           in sorted(attrs.items()))
    else:
        attr_str = ''
    if content:
        return '\n'.join('<%s%s>%s</%s>' %
                         (name, attr_str, c, name) for c in content)
    else:
        return '<%s%s />' % (name, attr_str)
```

The tag function can be invoked in many ways, as Example 5-11 shows.

*Example 5-11. Some of the many ways of calling the tag function from Example 5-10.*

```python
>>> tag('br')
'<br />'
>>> tag('p', 'hello')
'<p>hello</p>'
>>> print(tag('p', 'hello', 'world'))
<p>hello</p>
<p>world</p>
>>> tag('p', 'hello', id=33)
'<p id="33">hello</p>'
>>> print(tag('p', 'hello', 'world', cls='sidebar'))
<p class="sidebar">hello</p>
<p class="sidebar">world</p>
>>> tag(content='testing', name="img")
'<img content="testing" />'
>>> my_tag = {'name': 'img', 'title': 'Sunset Boulevard',
...           'src': 'sunset.jpg', 'cls': 'framed'}
>>> tag(**my_tag)
'<img class="framed" src="sunset.jpg" title="Sunset Boulevard" />'
```

A single positional argument produces an empty tag with that name.

Any number of arguments after the first are captured by *content as a tuple.

Keyword arguments not explicitly named in the tag signature are captured by **attrs as a dict.

The cls parameter can only be passed as a keyword argument.

Even the first positional argument can be passed as a keyword when tag is called.

Prefixing the my_tag dict with ** passes all its items as separate arguments which are then bound to the named parameters, with the remaining caught by `**attrs`.

Keyword-only arguments are a new feature in Python 3. In Example 5-10 the cls parameter can only be given as a keyword argument—it will never capture unnamed positional arguments. To specify keyword-only arguments when defining a function, name them after the argument prefixed with *. If you don’t want to support variable positional arguments but still want keyword-only arguments, put a * by itself in the signature, like this:

```python
>>> def f(a, *, b):
...     return a, b
...
>>> f(1, b=2)
(1, 2)
```

Note that keyword-only arguments do not need to have a default value: they can be mandatory, like b in the example above.

注意，仅关键字参数不需要拥有默认值：这些值是强制的，就像上面例子中的b那样。

We now move to the introspection of function parameters, starting with a motivating example from a web framework, and on through introspection techniques.

我们现在进入函数参数的内省的学习，并从一个富有启发web框架例子开始彻底了解内省的技术。

## Retrieving information about parameters
## 重新取回参数信息
An interesting application of function introspection can be found in the Bobo HTTP micro-framework. To see that in action, consider a variation of the Bobo tutorial “Hello world” application in Example 5-12.

你可以在Bobo HTTP微框架中发现一个有趣的函数内省应用。

*Example 5-12. Bobo knows that hello requires a person argument, and retrieves it from the HTTP request.*

```python
import bobo

@bobo.query('/')
def hello(person):
    return 'Hello %s!' % person
```

The bobo.query decorator integrates a plain function such as hello with the request handling machinery of the framework. We’ll cover decorators in Chapter 7—that’s not the point of this example here. The point is that Bobo introspects the hello function and finds out it needs one parameter named person to work, and it will retrieve a parameter with that name from the request and pass it to hello, so the programmer does not need to touch the request object at all.

If you install Bobo and point its development server to the code above (e.g. bobo -f hello.py), a hit on the URL http://localhost:8080/ will produce the message “Missing form variable person” with a 403 HTTP code. This happens because Bobo understands that the person argument is required to call hello, but no such name was found in the request. Example 5-13 is a shell session using curl to show this behavior.

*Example 5-13. Bobo issues a 403 forbidden response if there are missing function arguments in the request; curl -i is used to dump the headers to standard output.*

```python
$ curl -i http://localhost:8080/
HTTP/1.0 403 Forbidden
Date: Thu, 21 Aug 2014 21:39:44 GMT
Server: WSGIServer/0.2 CPython/3.4.1
Content-Type: text/html; charset=UTF-8
Content-Length: 103

<html>
<head><title>Missing parameter</title></head>
<body>Missing form variable person</body>
</html>
```

However if you get http://localhost:8080/?person=Jim, the response will be the string 'Hello Jim!'. See Example 5-14.

*Example 5-14. Passing*

```python
$ curl -i http://localhost:8080/?person=Jim
HTTP/1.0 200 OK
Date: Thu, 21 Aug 2014 21:42:32 GMT
Server: WSGIServer/0.2 CPython/3.4.1
Content-Type: text/html; charset=UTF-8
Content-Length: 10

Hello Jim!
```

How does Bobo know what are the parameter names required by the function, and whether they have default values or not?

Bobo如何知道函数需要什么参数，函数是否拥有默认值？

Within a function object, the `__defaults__` attribute holds a tuple with the default values of positional and keyword arguments. The defaults for keyword-only arguments appear in `__kwdefaults__`. The names of the arguments, however, are found within the `__code__` attribute, which is a reference to a code object with many attributes of its own.

在一个函数对象内部，`__defaults__`属性拥有一个含有位置参数、关键参数的默认值组成的元祖。默认的仅关键字参数可以在`__kwdefaults__`中找到。不过，

To demonstrate the use of these attributes, we will inspect the function clip in a module clip.py, listed in Example 5-15.

为了说明这些属性的用法，在例子5-15，我们对位于模块clip.py中的clip函数进行检查。

*Example 5-15. Function to shorten a string by clipping at a space near the desired length.*

```python
def clip(text, max_len=80):
    """Return text clipped at the last space before or after max_len
    """
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ', 0, max_len)
        if space_before >= 0:
            end = space_before
        else:
            space_after = text.rfind(' ', max_len)
            if space_after >= 0:
                end = space_after
    if end is None:  # no spaces were found
        end = len(text)
    return text[:end].rstrip()
```

Example 5-16 shows the values of __defaults__, __code__.co_varnames and __code__.co_argcount for the clip function listed above.

*Example 5-16. Extracting information about the function arguments.*

```python
>>> from clip import clip
>>> clip.__defaults__
(80,)
>>> clip.__code__  # doctest: +ELLIPSIS
<code object clip at 0x...>
>>> clip.__code__.co_varnames
('text', 'max_len', 'end', 'space_before', 'space_after')
>>> clip.__code__.co_argcount
2
```

As you can see, this is not the most convenient arrangement of information. The argument names appear in __code__.co_varnames, but that also includes the names of the local variables created in the body of the function. Therefore the argument names are the first N strings, where N is given by __code__.co_argcount which—by the way—does not include any variable arguments prefixed with * or **. The default values are identified only by their position in the __defaults__ tuple, so to link each with the respective argument you have to scan from last to first. In the example, we have two arguments, text and max_len, and one default, 80, so it must belong to the last argument, max_len.

This is awkward.

Fortunately there is a better way: the inspect module.

Take a look at Example 5-17.

*Example 5-17. Extracting the function signature.*

```python
>>> from clip import clip
>>> from inspect import signature
>>> sig = signature(clip)
>>> sig  # doctest: +ELLIPSIS
<inspect.Signature object at 0x...>
>>> str(sig)
'(text, max_len=80)'
>>> for name, param in sig.parameters.items():
...     print(param.kind, ':', name, '=', param.default)
...
POSITIONAL_OR_KEYWORD : text = <class 'inspect._empty'>
POSITIONAL_OR_KEYWORD : max_len = 80
```

Much better: inspect.signature returns an inspect.Signature object, which has a parameters attribute that lets you read an ordered mapping of names to inspect.Parameter objects. Each Parameter instance has attributes such as name, default and kind. The special value inspect._empty denotes parameters with no default—which makes sense considering that None is a valid—and popular—default value.

The kind attribute holds one of five possible values from _ParameterKind class:
POSITIONAL_OR_KEYWORD
a parameter that may be passed as a positional or as a keyword argument (most Python function parameters are of this kind).
VAR_POSITIONAL
a tuple of positional parameters.
VAR_KEYWORD
a dict of keyword parameters.
KEYWORD_ONLY
a keyword-only parameter (new in Python 3).
POSITIONAL_ONLY

a positional-only parameter; currently unsupported by Python function declaration syntax, but exemplified by existing functions implemented in C—like divmod—that do not accept parameters passed by keyword.

Besides name, default and kind, inspect.Parameter objects have an annotation attribute which is usually inspect._empty but may contain function signature metadata provided via the new annotations syntax in Python 3 (annotations are covered in the next section).

An inspect.Signature object has a bind method that takes any number of arguments and binds them to the parameters in the signature, applying the usual rules for matching actual arguments to formal parameters. This can be used by a framework to validate arguments prior to the actual function invocation.

*Example 5-18. Binding the function signature from the tag function in Example 5-10 do a dict of arguments.*

```python
>>> import inspect
>>> sig = inspect.signature(tag)
>>> my_tag = {'name': 'img', 'title': 'Sunset Boulevard',
...           'src': 'sunset.jpg', 'cls': 'framed'}
>>> bound_args = sig.bind(**my_tag)
>>> bound_args
<inspect.BoundArguments object at 0x...>
>>> for name, value in bound_args.arguments.items():
...     print(name, '=', value)
...
name = img
cls = framed
attrs = {'title': 'Sunset Boulevard', 'src': 'sunset.jpg'}
>>> del my_tag['name']
>>> bound_args = sig.bind(**my_tag)
Traceback (most recent call last):
  ...
TypeError: 'name' parameter lacking default value
```

Get the signature from tag function in Example 5-10.

Pass a dict of arguments to .bind().

An inspect.BoundArguments object is produced.

Iterate over the items in bound_args.arguments, which is an OrderedDict, to display the names and values of the arguments.

Remove the mandatory argument name from my_tag.

Calling sig.bind(`**my_tag`) raises a TypeError complaining of the missing name parameter.

This is shows how the Python Data Model, with the help of inspect, exposes the same machinery the interpreter uses to bind arguments to formal parameters in function calls.

Frameworks and tools like IDEs can use this information to validate code. Another feature of Python 3, function annotations, enhances the possible uses of this, as we will see next.

## Function annotations
## 函数注解
Python 3 provides syntax to attach metadata to the parameters of a function declaration and its return value. Example 5-19 is an annotated version of Example 5-15. The only differences are in the first line.

*Example 5-19. Annotated clip function.*

```python
def clip(text:str, max_len:'int > 0'=80) -> str:
    """Return text clipped at the last space before or after max_len
    """
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ', 0, max_len)
        if space_before >= 0:
            end = space_before
        else:
            space_after = text.rfind(' ', max_len)
            if space_after >= 0:
                end = space_after
    if end is None:  # no spaces were found
        end = len(text)
    return text[:end].rstrip()
```

The annotated function declaration.

Each argument in the function declaration may have an annotation expression preceded by :. If there is a default value, the annotation goes between the argument name and the = sign. To annotate the return value, add -> and another expression between the ) and the : at the tail of the function declaration. The expressions may be of any type. The most common types used in annotations are classes, like str or int, or strings, like 'int > 0', as seen in the annotation for max_len in Example 5-19.

No processing is done with the annotations. They are merely stored in the __annotations__ attribute of the function, a dict:

```python
>>> from clip_annot import clip
>>> clip.__annotations__
{'text': <class 'str'>, 'max_len': 'int > 0', 'return': <class 'str'>}
```

The item with key 'return' holds the return value annotation marked with -> in the function declaration in Example 5-19.

The only thing Python does with annotations is to store them in the __annotations__ attribute of the function. Nothing else: no checks, enforcement, validation, or any other action is performed. In other words, annotations have no meaning to the Python interpreter. They are just metadata that may be used by tools, such as IDEs, frameworks and decorators. At this writing no tools that use this metadata exist in the standard library, except that inspect.signature() knows how to extract the annotations, as Example 5-20 shows.

*Example 5-20. Extracting annotations from the function signature.*

```python
>>> from clip_annot import clip
>>> from inspect import signature
>>> sig = signature(clip)
>>> sig.return_annotation
<class 'str'>
>>> for param in sig.parameters.values():
...     note = repr(param.annotation).ljust(13)
...     print(note, ':', param.name, '=', param.default)
<class 'str'> : text = <class 'inspect._empty'>
'int > 0'     : max_len = 80
```

The signature function returns a Signature object which has a return_annotation attribute and a parameters dictionary mapping parameter names to Parameter objects. Each Parameter object has its own annotation attribute. That’s how Example 5-20 works.

In the future, frameworks such as Bobo could support annotations to further automate request processing. For example, an argument annotated as price:float may be automatically converted from query string to the float expected by the function; a string annotation like quantity:'int > 0' might be parsed to perform conversion and validation of a parameter.

The biggest impact of functions annotations will probably not be dynamic settings such as Bobo, but in providing optional type information for static type checking in tools like IDEs and linters.

After this deep dive into the anatomy of functions, the remaining of this chapter covers the most useful packages in the standard library supporting functional programming.

## Packages for functional programming
Although Guido makes it clear that Python does not aim to be a functional programming language, a functional coding style can be used to good extent, thanks to the support of packages like operator and functools, which we cover in the next two sections.

### The operator module
Often in functional programming it is convenient to use an arithmetic operator as a function. For example, suppose you want to multiply a sequence of numbers to calculate factorials without using recursion. To perform summation you can use sum, but there is no equivalent function for multiplication. You could use reduce—as we saw in Modern replacements for map, filter and reduce—but this requires a function to multiply two items of the sequence. Here is how to solve this using lambda:

*Example 5-21. Factorial implemented with reduce and an anonymous function.*

```python
from functools import reduce

def fact(n):
    return reduce(lambda a, b: a*b, range(1, n+1))
```

To save you the trouble of writing trivial anonymous functions like lambda a, b: a*b, the operator module provides function equivalents for dozens of arithmetic operators. With it, we can rewrite Example 5-21 as Example 5-22.

*Example 5-22. Factorial implemented with reduce and operator.mul.*

```python
from functools import reduce
from operator import mul

def fact(n):
    return reduce(mul, range(1, n+1))
```

Another group of one-trick lambdas that operator replaces are functions to pick items from sequences or read attributes from objects: itemgetter and attrgetter actually build custom functions to do that.

Example 5-23 shows a common use of itemgetter: sorting a list of tuples by the value of one field. In the example, the cities are printed sorted by country code (field 1). Essentially, itemgetter(1) does the same as lambda fields:
fields[1]: create a function that, given a collection, returns the item at index 1.

*Example 5-23. Demo of itemgetter to sort a list of tuples (data from Example 2-8).*

```python
>>> metro_data = [
...     ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
...     ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
...     ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
...     ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
...     ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
... ]
>>>
>>> from operator import itemgetter
>>> for city in sorted(metro_data, key=itemgetter(1)):
...     print(city)
...
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
('Mexico City', 'MX', 20.142, (19.433333, -99.133333))
('New York-Newark', 'US', 20.104, (40.808611, -74.020386))
```

If you pass multiple index arguments to itemgetter, the function it builds will return tuples with the extracted values:

如果你传递多个索引参数到itemgetter，函数将返回拥有提取值构成的元组：

```python
>>> cc_name = itemgetter(1, 0)
>>> for city in metro_data:
...     print(cc_name(city))
...
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('US', 'New York-Newark')
('BR', 'Sao Paulo')
```

Because itemgetter uses the [] operator, it supports not only sequences but also mappings and any class that implements `__getitem__`.

A sibling of `itemgetter` is `attrgetter`, which creates functions to extract object attributes by name. If you pass attrgetter several attribute names as arguments, it also returns a tuple of values. In addition, if any argument name contains a . (dot), attrgetter navigates through nested objects to retrieve the attribute. These behaviors are shown in Example 5-24. This is not the shortest console session because we need to build a nested structure to showcase the handling of dotted attributes by attrgetter.

*Example 5-24. Demo of attrgetter to process a previously defined list of namedtuple called metro_data (the same list that appears in Example 5-23).*

```python
>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long')  #
>>> Metropolis = namedtuple('Metropolis', 'name cc pop coord')  #
>>> metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long))  #
...     for name, cc, pop, (lat, long) in metro_data]
>>> metro_areas[0]
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722, long=139.691667))
>>> metro_areas[0].coord.lat  #
35.689722
>>> from operator import attrgetter
>>> name_lat = attrgetter('name', 'coord.lat')  #
>>>
>>> for city in sorted(metro_areas, key=attrgetter('coord.lat')):  #
...     print(name_lat(city))  #
...
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)
```

Use namedtuple to define LatLong.

Also define Metropolis.

Build metro_areas list with Metropolis instances; note the nested tuple unpacking to extract (lat, long) and use them o build the LatLong for the coord attribute of Metropolis.

Reach into element metro_areas[0] to get its latitude.

Define an attrgetter to retrieve the name and the coord.lat nested attribute.

Use attrgetter again to sort list of cities by latitude.

Use the attrgetter defined in <5> to show only city name and latitude.

Here is a partial list of functions defined in operator (names starting with _ are omitted, as they are mostly implementation details):

```python
>>> [name for name in dir(operator) if not name.startswith('_')]
['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains',
'countOf', 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt',
'iadd', 'iand', 'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul',
'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift',
'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',
'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne',
'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub',
'truediv', 'truth', 'xor']
```

Most of the 52 names above are self-evident. The group of names prefixed with i and the name of another operator—e.g. iadd, iand etc.—correspond to the augmented assignment operators—e.g. +=, &= etc. These change their first argument in-place, if it is mutable; if not, the function works like the one without the i prefix: it simply returns the result of the operation.

Of the remaining operator functions, methodcaller is the last we will cover. It is somewhat similar to attrgetter and itemgetter in that it creates a function on-the-fly. The function it creates calls a method by name on the object given as argument.

*Example 5-25. Demo of methodcaller: second test shows the binding of extra arguments.*

```python
>>> from operator import methodcaller
>>> s = 'The time has come'
>>> upcase = methodcaller('upper')
>>> upcase(s)
'THE TIME HAS COME'
>>> hiphenate = methodcaller('replace', ' ', '-')
>>> hiphenate(s)
'The-time-has-come'
```

The first test in Example 5-25 is there just to show methodcaller at work, but if you need to use the str.upper as a function you can just call it on the str class and pass a string as argument, like this:

```python
>>> str.upper(s)
'THE TIME HAS COME'
```

The second test in Example 5-25 shows that methodcaller can also do a partial application to freeze some arguments, like the functools.partial function does. That is our next subject.

### Freezing arguments with functools.partial
### 使用functools.partial冻结参数
The functools module brings together a handful of higher-order functions. The best known of them is probably reduce, which was covered in Modern replacements for map, filter and reduce. Of the remaining functions in functools the most useful is partial and its variation, partialmethod.

The functools.partial is a higher-order function that allows partial application of a function. Given a function, a partial application produces a new callable with some of the arguments of the original function fixed. This is useful to adapt a function that takes one or more arguments to an API that requires a callback with less arguments. Example 5-26 is a trivial demonstration.

*Example 5-26. Using partial to use a 2-argument function where a 1-argument callable is required.*

```python
>>> from operator import mul
>>> from functools import partial
>>> triple = partial(mul, 3)
>>> triple(7)
21
>>> list(map(triple, range(1, 10)))
[3, 6, 9, 12, 15, 18, 21, 24, 27]
```

Create new triple function from mul, binding first positional argument to 3.

Test it.

Use triple with map; mul would not work with map in this example.

A more useful example involves the unicode.normalize function that we saw in Normalizing Unicode for saner comparisons. If you work with text from many languages, you may want to apply unicode.normalize('NFC', s) to any string s before comparing or storing it. If you do that often, its handy to have an nfc function to do that, as in Example 5-27.

*Example 5-27. Building a convenient Unicode normalizing function with partial.*

```python
>>> import unicodedata, functools
>>> nfc = functools.partial(unicodedata.normalize, 'NFC')
>>> s1 = 'café'
>>> s2 = 'cafe\u0301'
>>> s1, s2
('café', 'café')
>>> s1 == s2
False
>>> nfc(s1) == nfc(s2)
True
```

partial takes a callable as first argument, followed by an arbitrary number of positional and keyword arguments to bind.

Example 5-28 shows the use of partial with the tag function from Example 5-10, to freeze one positional argument and one keyword argument.

*Example 5-28. Demo of partial applied to the function tag from Example 5-10.*

```python
>>> from tagger import tag
>>> tag
<function tag at 0x10206d1e0>
>>> from functools import partial
>>> picture = partial(tag, 'img', cls='pic-frame')
>>> picture(src='wumpus.jpeg')
'<img class="pic-frame" src="wumpus.jpeg" />'
>>> picture
functools.partial(<function tag at 0x10206d1e0>, 'img', cls='pic-frame')
>>> picture.func
function tag at 0x10206d1e0>
>>> picture.args
('img',)
>>> picture.keywords
{'cls': 'pic-frame'}
```

Import tag from Example 5-10 and show its id.

Create picture function from tag by fixing the first positional argument with 'img' and the cls keyword argument with 'pic-frame'.

picture works as expected.

partial() returns a functools.partial object[45].

A functools.partial object has attributes providing access to the original function and the fixed arguments.

The functools.partialmethod function (new in Python 3.4) does the same job as partial, but is designed to work with methods.

An impressive functools function is lru_cache, which does memoization—a form of automatic optimization that works by storing the results of function calls to avoid expensive recalculations. We will cover it in Chapter 7, where decorators are explained, along with other higher-order functions designed to be used as decorators: singledispatch and wraps.

## Chapter summary
## 本章总结
The goal of this chapter was to explore the first-class nature of functions in Python. The main ideas are that you can assign functions to variables, pass them to other functions, store them in data structures and access function attributes, allowing frameworks and tools to act on that information. Higher-order functions, a staple of functional programming, are common in Python—even if the use of map, filter and reduce is not as frequent as it was—thanks to list comprehensions (and similar constructs like generator expressions) and the appearance of reducing built-ins like sum, all and any. The sorted, min, max built-ins, and functools.partial are examples of commonly used higher-order functions in the language.

Callables come in seven different flavors in Python, from the simple functions created with lambda to instances of classes implementing `__call__`. They can all be detected by the callable() built-in. Every callable supports the same rich syntax for declaring formal parameters, including keyword-only parameters and annotations—both new features introduced with Python 3.

Python functions and their annotations have a rich set of attributes that can be read with the help of the inspect module, which includes the Signature.bind method to apply the flexible rules that Python uses to bind actual arguments to declared parameters.

Lastly, we covered some functions from the operator module and functools.partial, which facilitate functional programming by minimizing the need for the functionally-challenged lambda syntax.

## Further reading  深入阅读
The next two chapters continue our exploration of programming with function objects. Chapter 6 shows how first-class functions can simplify some classic Object Oriented design patterns, while Chapter 7 dives into function decorators—a special kind of higher-order function—and the closure mechanism that makes them work.

Chapter 7 of the Python Cookbook, 3rd. edition (O’Reilly, 2013), by David Beazley and Brian K. Jones, is an excellent complement to the current chapter as well as Chapter 7 of this book, covering mostly the same concepts with a different approach.

In the Python Language Reference, chapter “3. Data model”, section 3.2 The standard type hierarchy presents the seven callable types, along with all the other built-in types.

The Python-3-only features discussed in this chapter have their own PEPs: PEP 3102—Keyword-Only Arguments and PEP 3107—Function Annotations.

For more about the current (as of mid-2014) use of annotations, two Stack Overflow questions are worth reading: What are good uses for Python3’s “Function Annotations”, has a practical answer and insightful comments by Raymond Hettinger, and the answer for What good are Python function annotations? quotes extensively from Guido van Rossum.

PEP 362—Function Signature Object is worth reading if you intend to use the inspect module which implements that feature.

A great introduction to functional programming in Python is A. M. Kuchling’s Python Functional Programming HOWTO. The main focus of that text, however, is on the use of iterators and generators, which are the subject of Chapter 14.

fn.py is a package to support Functional programming in Python 2 and 3. According to its author, Alexey Kachayev, fn.py provides “implementation of missing features to enjoy FP” in Python. It includes a @recur.tco decorator that implements tail-call optimization for unlimited recursion in Python, among many other functions, data structures and recipes.

The StackOverflow question Python: Why is functools.partial necessary? has a highly informative (and funny) reply by Alex Martelli, author of the classic Python in a Nutshell.

Jim Fulton’s Bobo was probably the first Web framework that deserved to be called Object Oriented. If you were intrigued by it and want to learn more about its modern rewrite, start at its Introduction. A little of the early history of Bobo appears in a comment by Phillip J. Eby in a discussion at Joel Spolsky’s blog.

>### SOAPBOX  演讲台
>About Bobo
>I owe my Python career to Bobo. I used it in my first Python Web project, in 1998. I discovered Bobo while looking for an object-oriented way to code web applications, after trying Perl and Java alternatives.

>In 1997 Bobo had pioneered the object publishing concept: direct mapping from URLs to a hierarchy of objects, with no need to configure routes. I was hooked when I saw the beauty of this. Bobo also featured automatic HTTP query handling based on analysis of the signatures of the methods or functions used to handle requests.

>Bobo was created by Jim Fulton, known as “The Zope Pope” thanks to his leading role in the development of the Zope framework, the foundation of the Plone CMS, SchoolTool, ERP5 and other large-scale Python projects. Jim is also the creator of ZODB—the Zope Object Database—a transactional object database that provides ACID (atomicity, consistency, isolation and durability), designed for ease of use from Python.

>Jim has since rewritten Bobo from scratch to support WSGI and modern Python (including Python 3). As of this writing, Bobo uses the six library to do the function introspection, in order to be compatible with Python 2 and Python 3 in spite of the changes in function objects and related APIs.

>### Is Python a functional language?  Python是函数化语言吗？
Around the year 2000 I was at a training in the US when Guido van Rossum dropped by the classroom (he was not the instructor). In the Q&A that followed, somebody asked him which features of Python were borrowed from other languages. His answer: “Everything that is good in Python was stolen from other languages.”

>Shriram Krishnamurthi, professor of Computer Science at Brown University, starts his Teaching Programming Languages in a Post-Linnaean Age paper with this:
Programming language “paradigms” are a moribund and tedious legacy of a bygone age. Modern language designers pay them no respect, so why do our courses slavishly adhere to them?

>In that paper, Python is mentioned by name in this passage:

>What else to make of a language like Python, Ruby, or Perl? Their designers have no patience for the niceties of these Linnaean hierarchies; they borrow features as they wish, creating melanges that utterly defy characterization.

>Krishnamurthi submits that instead of trying to classify languages in some taxonomy, it’s more useful to consider them as aggregations of features.

>Even if it was not Guido’s goal, endowing Python with first-class functions opened the door to functional programming. In his post Origins of Python’s “Functional” Features, he tells that map, filter and reduce were the motivation for adding lambda to Python in the first place. All of these features were contributed together by Amrit Prem for Python 1.0 in 1994 (according to Misc/HISTORY in the CPython source code).

>lambda, map, filter and reduce first appeared in Lisp, the original functional language. However, Lisp does not limit what can be done inside a lambda, because everything in Lisp is an expression. Python uses a statement-oriented syntax in which expressions cannot contain statements, and many language constructs are statements—including try/catch, which is what I miss most often when writing lambdas. This is the price to pay for Python’s highly readable syntax[46]. Lisp has many strengths, but readability is not one of them.

>Ironically, stealing the list comprehension syntax from another functional language—Haskell—significantly diminished the need for map and filter, and also for lambda.

>Besides the limited anonymous function syntax, the biggest obstacle to wider adoption of functional programming idioms in Python is the lack of tail-recursion elimination, an optimization that allows memory-efficient computation of a function that makes a recursive call at the “tail” of its body. In another blog post, Tail Recursion Elimination Guido gives several reasons why such optimization is not a good fit for Python. That post is a great read for the technical arguments, but even more so because the first three and most important reasons given are usability issues. It is no accident that Python is a pleasure to use, learn and teach. Guido made it so.

>So there you have it: Python is, by design, not a functional language—whatever that means. Python just borrows a few good ideas from functional languages.

>### The problem with anonymous functions 使用匿名函数带来的问题
Beyond the Python-specific syntax constraints, anonymous functions have a serious drawback in every language: they have no name.

>I am only half joking here. Stack traces are easier to read when functions have names. Anonymous functions are a handy shortcut, people have fun coding with them, but sometimes they get carried away—especially if the language and environment encourage deep nesting of anonymous functions, like JavaScript on Node.js. Lots of nested anonymous functions make debugging and error handling hard. Asynchronous programming in Python is more structured, perhaps because the limited lambda demands it. I promise to write more about asynchronous programming in the future, but this subject must be deferred to Chapter 18. By the way, promises, futures and deferreds are concepts used in modern asynchronous APIs. Along with coroutines, they provide an escape from the so called “callback hell”. We’ll see how callback-free asynchronous programming works in From callbacks to futures and coroutines.

[43] Origins of Python’s “Functional” Features, in Guido’s Python History blog

[44] Usually calling a class creates an instance of the same class, but other behaviors are possible by overriding `__new__`. We’ll see an example of this in Flexible object creation with `__new__`

[45] The source code for functools.py reveals that the functools.partial class is implemented in C and is used by default. If that is not available, a pure-Python implementation of partial is available since Python 3.4.in the functools module.

[46] There also the problem of lost indentation when pasting code to Web forums, but I digress.

repository: leixiayang/-Python

path: /第五章－一级函数.md

path: /第五章－一级函数.md

repo_name: leixiayang/-Python


text:
# Moocher

> Web content scraper

[![CircleCI](https://circleci.com/gh/schne324/moocher.svg?style=svg)](https://circleci.com/gh/schne324/moocher)

## Installation

```bash
$ npm install --save moocher # or yarn add moocher
```

## Usage

```js
new Moocher(urls, options);
```

- `urls` {String|Array} a single string url or an array of urls to scrape content from.
- `options` {Object} (optional) the configuration object.
  - `limit` {Number} (optional) the number of concurrent requests to make while scraping. Defaults to `undefined` which does not enforce a concurrency limit (all requests will be run in parallel).

## API
Moocher emits the following events:

- `"mooch"`: Emits for each response. The callback receives the following arguments:
  - `$`: The cheerio-loaded document. This means you can just use jQuery methods on the response document.
  - `url`: The original url passed to Moocher.
  - `response`: The full response object
- `"error"`: Emits when a single request fails
- `"complete"`: Emits when the moocher is done mooching.

## Example
```js
const mooch = new Moocher([
  'https://url-1.com',
  'http://url-2.com',
  'http://url-3.com',
  'https://url-4.com',
  'http://url-5.com'
], {
  limit: 2 // allow only 2 concurrent requests
});

mooch
  // emitted for each web page mooched
  .on('mooch', ($, url) => {
    const $h1 = $('h1');
    titles.push($h1.text());
  })
  // emitted if any request fails
  .on('error', (err) => console.error(err))
  // emitted when all urls have been mooched
  .on('complete', () => {
    console.log(`All titles have been mooched: ${titles.join(', ')}`);
  })
  // start mooching!
  .start();
```

license: MIT

gha_language: JavaScript

gha_license_id: MIT


text:
---
layout: post
title: 'Super Smash Bros Locator Obituary'
tags: [projects]
description: >
  The end of an era.
---

I recently received an email from Google notifying me that they would restrict an app I made a
while back if I did not provide a privacy policy or whatever. This app, Super Smash Bros Locator,
was something I made a while back, a child spawned from my love of creation and [Super Smash
Brothers Melee for the Nintendo Gamecube](https://twitter.com/onlypostsmelee). In short, the idea
was that you could find people around you on a Google Maps layout, meet up, and play smash. Anyway,
I logged onto my my developer console to see what the issue was and quickly set my eyes on
some heartbreaking statistics.

![sad-statistics](/public/img/ssbl/sad-statistics.png "feels bad")

I took this as a sign that I should euthanize my project before something uncouth happens like
Nintendo taking legal action against me or something; I don't know. So I want to give my first
ever side project a proper funeral before I put it to sleep.

---

I liken the life of Super Smash Bros Locator to that of the butterfly, kind of. As a caterpillar,
Super Smash Bros Locator was clunky, slow, lacking elegant design, ultimately
unfit to survive, but nonetheless cute. For flaws, off the top of my head, I remember handwritten SQL
statements, a backend that was literally a fat if block that conditioned on a string passed in
through the HTTP headers, and a irrational mix of Android activities and fragments on the frontend.
However, it was a good effort. Having never touched backend before, I had something working
for a single, uh I mean simple, use case.

At some point along this caterpillar's life, development slowed down as I had implemented a good set
of basic features, and my service passed my test case of logging in and randomly inputting stuff in
an attempt to break something. Having confirmed this excellent robustness, I was in
a "now what?" kind of state. At the time, I was also a freshman desperately trying to land a summer
internship, and among my interactions with various engineers, one of them suggested that I should
just release my app into the wild. Also as a desperate freshman, I took this advice as an
unquestionable mandate of heaven, and so I [released](https://www.reddit.com/r/smashbros/comments/2w5vd9/ive_created_an_android_app_to_help_you_play_smash/) it. As soon as my caterpillar landed its
fuzzy feet on the jungle floor (the Google Play store), it instantly combusted and was trampled by
the jungle's assortment of creatures. All sorts of bugs, unexpected features, and null pointer
exceptions were reported.
I would obsessively check the number of entries within the MySQL database and naturally conclude that
I was simply the best programmer to ever do it.

Seeing the large influx of users and even larger influx of bug reports, I decided to overhaul
everything. I got the help of my pair programming partner, [Ashwin](http://madavan.me/), to rewrite
the backend with Spring, Hibernate, and all those good web technologies goodies that I was not
aware of. I rewrote the Android app part, adding some nice material design elements, consistent
activity/fragment usage, etc. If you have been following my caterpillar analogy, this is the part
where the caterpillar is chilling in the cocoon.

After a couple weeks of work, our cocoon was ready to hatch, and we [re-released](https://www.reddit.com/r/smashbros/comments/317fob/ive_created_an_android_app_that_helps_you_play/) with the shiny new
backend and an equally sleek frontend to match. Unfortunately, what we saw and what our users saw
were complete opposites. We saw a sleek, 2.0, VR ready, deep TensorFlow ready, fresh butterfly,
but our users saw the same unfit-to-survive caterpillar with a pair of paper-mache wings haphazardly
glued onto its back.

Essentially, users saw the same clunky app the I released the first time around. Given, the
polished new version did have its own share of bugs. For instance, on this release, upon revamping
the backend, everyone ended up in some large public group chat when they would try and send an
individual message. It _was_ interesting to see a massive conversation between hundreds of people,
but it was still unintentional.

A couple bug fixes and app updates later, here we are. A year ago, the backend would have gotten
around 50 hits a day, but that has dwindled. I've determined that the ~10 hits I get per
day is no longer worth the $15 I spend a month on maintaining the EC2 instance, and the privacy
policy was the final straw. The app lost a lot of crucial momentum that it should have
maintained from the first release. I feel like if everything went smoothly at the beginning, the app
might have had a larger base of regular users and grown to take a spot right next to Facebook
Messenger in top free apps, but somehow that didn't happen.

In conclusion, I would say the most valuable thing I got from this experience is a taste of what
it's like to create something and have people use it. Now I know what some of you might be
thinking. _Wow Eric. That's pretty dumb.  Yeah I guess you could. I don't really know what to say to that.


text:
## Problem to solve
`AB - CD = EF, EF + GH = PPP` where ABCDEFGHP are distinct and in Range(0,1,2,...,9)

## Backgroud

(AB - CD = EF) + GH = PPP problem, inspired by golden post:

考起碩士生的小一數學題(ppp)解法 - 香港高登
http://m2.hkgolden.com/view.aspx?message=6307521&type=SW&page=1

Credit to golden son

#### Contribution

1. Fork me
2. Impl your language/algo under dir `<language>-<algo>` format, e.g. `python-bruteforce`
3. Add comment/script for others to build & run
4. Add example output in comment / create a output.txt
5. Make sure your pull request commits are meaningful!
6. Submit Pull Request

#### Create README.md (Optional)
We strongly recommend you to add a README.md in your folder, here are some of the questions that developers wonder to know :)
* How efficient is your solution?
* Is there any room of improvements?
* What are the Time Complexity & Space Complexity of your algos?

#### Recommended Folder Structure
```
├── java-bruteforce/
|     ├── abcdefghppp.java
|     ├── output.txt
|     ├── README.md (Optional)
|     ├── run.sh (Optional)
|     |
├── haskell-permutation/
|     ├── abcdefghppp.hs
|     ├── output.txt
|     ├── README.md (Optional)
|     ├── Makefile (Optional)
...
```
## Advance Challenges
PCs in this age have very powerful computation power. Thus, Base 10 `AB - CD = EF, EF - GH = PPP` is too easy to compute the result. That's why someone even said that brute-force is also be accepted.

Let's try more complicated scenario, all alphabats repersent a single value (in base) & distinct. It will be easier to see the significant performance difference of each approach.

#### Advance
Base 16 `AB - CD = EF, EF - GH = PPP` (Width = 2)

Base 22 `AB - CD = EF, EF - GH = PPP` (Width = 2)

Base 28 `AB - CD = EF, EF - GH = PPP` (Width = 2)

Base 34 `AB - CD = EF, EF - GH = PPP` (Width = 2)

Base 17 `ABCD - EFGH = IJKL, IJKL + MNOP = QQQQQ` (Width = 4)

Base 21 `ABCD - EFGH = IJKL, IJKL + MNOP = QQQQQ` (Width = 4)

Base 25 `ABCD - EFGH = IJKL, IJKL + MNOP = QQQQQ` (Width = 4)

Base 29 `ABCD - EFGH = IJKL, IJKL + MNOP = QQQQQ` (Width = 4)

...

** You must solve at least 2 of them **

All suggestions are welcome. Just modify this file and PR

#### output.txt rules
All output.txt in Advance MUST include the following information

* Machine used (Must be the first line)
* Total number of solutions
* First 50 solutions
* Time used for calculation
* include all Base result

#### Recommended Folder Structure
```
├── Advance/
|     ├── scala-optimized-permutation-parallel/
|     |     ├── abcdefghppp-w2.scala (Only handle width = 2)
|     |     ├── output_w2.txt        (w2 = width 2)
|     |     ├── README.md            (Optional)
|     |     ├── run.sh               (Optional)
|     ├── javascript-bruteforce/
|     |     ├── abcdefghppp-generic.js (Handle all width)
|     |     ├── output_w2.txt          (w2 = width 2)
|     |     ├── output_w4.txt          (w4 = width 4)
|     |     ├── README.md              (Optional)
|     |     ├── run.sh                 (Optional)
...
```

## TODO
- add more languages
- travis CI?

repository: mingchuno/ABCDEFGHPPP

gha_language: Common Lisp

repo_name: mingchuno/ABCDEFGHPPP


text:
# Horusec-Extensions

This project contains horusec extensions for development interfaces, which you can use to increase your productivity and make the tool easier to use.

## What is Horusec?
Horusec is an open source tool that improves identification of vulnerabilities in your project with just one command.

### For more details see our [DOCUMENTATION](https://zup-products.gitbook.io/horusec)

## Contributing

Read our [contributing guide](CONTRIBUTING.md) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to horusec.

## Communication

We have a few channels for contact, feel free to reach out to us at:

- [GitHub Issues](https://github.com/ZupIT/horusec-extensions/issues)
- [Zup Open Source Forum](https://forum.zup.com.br)

repository: lucasbrunozup/horusec-vscode-plugin

repo_name: lucasbrunozup/horusec-vscode-plugin


text:
---
layout: default
---

# 1996-12-06 - Re: PGP 5.0??

## Header Data

From: "Thomas C. Allard"<EMAIL_ADDRESS>To<EMAIL_ADDRESS>Message Hash: 543571a6b90cb5da1e60275f516b791509419cbd32107859f7f06951dc48bb4d

Message ID<EMAIL_ADDRESS>Reply To: \<9612060130.AA01059@ch1d157nwk\>

UTC Datetime: 1996-12-06 15:43:51 UTC

Raw Date: Fri, 6 Dec 1996 07:43:51 -0800 (PST)

## Raw message

```
{% raw  %}From: "Thomas C. Allard"<EMAIL_ADDRESS>Date: Fri, 6 Dec 1996 07:43:51 -0800 (PST)
To<EMAIL_ADDRESS>Subject: Re: PGP 5.0??
In-Reply-To: <9612060130.AA01059@ch1d157nwk>
Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

<EMAIL_ADDRESS>said:
> what are you guys talking about???  AFAIK, the most current,
> released,   version of PGP is 2.6.2.  Version 3 is not finished and
> anything you may get   your hands on is a prerelease version.  PGP 4
> and 5 simply don't exist!

PGP 4 is ViaCrypt's latest version of pgp.

It has some features that pgp 2.6.* doesn't have.

>From the User's Manual:
>
>     ViaCrypt PGP supports three types of keys:
>
>       Dual-Function Keys are keys that are interoperable and
> compatible  with pre-4.0 versions of ViaCrypt PGP. They can be used
> for  encryption/decryption and for digital signatures.
>
>       Single-Function, Encryption-Only Keys are keys that have been
> designated to be used for only encryption/decryption, and cannot be
> used for digital signatures.
>
>       Single-Function, Signature-Only Keys are keys that have been
> designated to be used for only digital signatures, and cannot be used
> for encryption/decryption.  Single function keys are not usable by
> Version 2.7.1 or earlier.

There is also a "business edition" with still other featuers, namely a
"Corporate Access Key".

See http://www.pgp.com/products/viacrypt-business.cgi

rgds-- TA<EMAIL_ADDRESS>I don't speak for the Federal Reserve Board, it doesn't speak for me.
pgp fingerprint: 10 49 F5 24 F1 D9 A7 D6  DE 14 25 C8 C0 E2 57 9D

{% endraw %}
```

## Thread

+ Return to [December 1996](/archive/1996/12)

+ Return to "[Adam Back <aba@dcs.ex.ac.uk>](/authors/adam_back_aba_at_dcs_ex_ac_uk_)"
+ Return to "[Andrew Loewenstern <andrew_loewenstern@il.us.swissbank.com>](/authors/andrew_loewenstern_andrew_loewenstern_at_il_us_swissbank_com_)"
+ Return to<EMAIL_ADDRESS>(John Anonymous MacDonald)](/authors/nobody_at_cypherpunks_ca_john_anonymous_macdonald_)"
+ Return to "["Thomas C. Allard" <m1tca00@FRB.GOV>](/authors/thomas_c_allard_m1tca00_at_frb_gov_)"
+ Return to "[William Knowles <erehwon@c2.net>](/authors/william_knowles_erehwon_at_c2_net_)"

+ _Unknown thread root_
  + 1996-12-05 (Wed, 4 Dec 1996 22:11:35 -0800 (PST)) - [Re: PGP 5.0??](/archive/1996/12/3dc1ff894773cd1a3134d560fba75ec47d816d7861a4c3afd9686255006b7a53) - _William Knowles<EMAIL_ADDRESS>    + 1996-12-06 (Thu, 5 Dec 1996 16:42:38 -0800 (PST)) - [Re: PGP 5.0??](/archive/1996/12/8f03df840ab0b532f3eb6f97cb52dfeddd508ac75ca6323a53cfa75e14470814) -<EMAIL_ADDRESS>(John Anonymous MacDonald)_
    + 1996-12-06 (Thu, 5 Dec 1996 17:30:25 -0800 (PST)) - [Re: PGP 5.0??](/archive/1996/12/b44d63d43803daed0c7fbf89eaff9f9ae5dce7a30a1ec98d8ca009f90407fbf3) - _Andrew Loewenstern<EMAIL_ADDRESS>      + 1996-12-06 (Fri, 6 Dec 1996 07:27:28 -0800 (PST)) - [Re: PGP 5.0??](/archive/1996/12/825b8b047ec41cecfbe4267505ffd8023fdb94793e4ef5f1c92f65ba6ade4d05) - _Adam Back<EMAIL_ADDRESS>      + 1996-12-06 (Fri, 6 Dec 1996 07:43:51 -0800 (PST)) - Re: PGP 5.0?? - _"Thomas C. Allard"<EMAIL_ADDRESS>


text:
# Personal Shopper

## Purpose

This application is designed to run on a internet addressable server in concert with Twilio to provide an easy way to remember the shopping. Text items to the twilio number whenever you remember. Then text 'list' to the Twilio number to be sent the current list.

## Usage

App is run by node server.js on the target machine

Then just text the Twilio number you specified in the config to add items to the list. Text list to the number to have the list text back to you.

## License

The MIT License (MIT)
Copyright © 2013 <Tom Townsend>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

repository: RadioactiveMouse/PersonalShopper

repo_name: RadioactiveMouse/PersonalShopper


text:
# CaDansa app

[![Dart](https://github.com/balfolk/cadansa-app/actions/workflows/dart.yml/badge.svg)](https://github.com/balfolk/cadansa-app/actions/workflows/dart.yml)

This is the [Flutter](https://flutter.dev/)-based mobile app for the [CaDansa festival](https://cadansa.nl). This app is designed to run on Android and iOS.

## Installation

### Part 0: Requirements

Any system will require about 10 GB of free disk space, and an installation of any Linux distribution, macOS, or Windows 10.

#### Linux

Most Linux distributions should not need any additional dependencies. The full list of required tools can be found near the top of the Flutter installation page.

#### macOS

Make sure you're on the latest version of macOS. Install XCode through the Mac App Store, open it, and press "Install" when the popup for additional components appears.
Then install the XCode command line tools by running `xcode-select --install` on the command line, followed by `sudo xcodebuild -license`.

#### Windows

Windows requires the most configuration to set up. Make sure to carefully follow the setup instructions in the Flutter documentation and you should be good to go.
Before starting, please ensure your Windows 10 system has all the latest updates and patches installed.

### Part 1: Installation and running tests

*  First, install Flutter and associated programs (such as Android Studio) according to the instructions here: https://flutter.dev/docs/get-started/install.
    *  If you install Git on Windows, make sure to select the option to commit using Unix-style line endings.
    *  Flutter automatically enables analytics reporting to Google. If you want to disable this, run `flutter config --no-analytics` on the command line.
    *  Make sure to follow the steps that help you set up Android Studio as an editor.
    *  The unofficial [Flutter Enhancement Suite](https://plugins.jetbrains.com/plugin/12693-flutter-enhancement-suite/) plugin for Android Studio is highly recommended, and .env and Markdown plugins can also come in handy.
*  Currently, this app builds against the `stable` channel of Flutter. Make sure that's your current channel by executing `flutter channel stable`.
*  Run `flutter upgrade` followed by `flutter update-packages` to update Flutter and its internal packages.
*  Accept the Android licenses using `flutter doctor --android-licenses`.
*  Open Android Studio and create a new project from this repository.
    * On an Apple Silicon (ARM) machine, _do not_ attempt to set Android Studio to full screen - use Windows -> Zoom instead. For an unknown reason full screen breaks the application.
    * You need to have an SSH key set up in order to do so.
    * Make sure to add it as a Flutter project. If you can't do that, first ensure you have gone through the entire set-up process of Flutter.
*  Head to Android Studio Settings -> Languages & Frameworks -> Dart and enable Dart support for this project. Set the Dart SDK location to `bin/cache/dart-sdk` relative your Flutter installation directory.
    * Android Studio Settings are located under Android Studio -> Preferences (or  ⌘,) on macOS and under File -> Settings on Linux and Windows.
*  The banner in Android Studio should change to give you the option to get packages; do so now. Wait for the downloads to complete.
    * If there's no banner, manually execute `flutter pub get`.
*  Set up a `.env` file in the top-level repository directory containing `CONFIG_URI=https://...`, where the URI points to a local or remote resource containing the configuration.
    * If you use a local file, add it to the `assets` section of the `pubspec.yaml`, and use the same (relative) path in the `.env` file. Make sure to not commit these changes!
*  Obtain the app & map fonts (or use your favourite fonts), and put them into `assets/fonts/app-font.otf` and `assets/fonts/map-{regular,bold,light}.otf`, respectively.

### Part 2a: Running the app on an Android Emulator

* Make sure that you have an Android Emulator of a recent Android SDK version (eg. API 30) set up and ready to go.
    * Starting with Ubuntu 19.10, 32-bit apps are no longer supported. Make sure you download and use a 64-bit Android image.
* Now you can start the application and debug it. Enjoy!

### Part 2b: Running the app on an iOS emulator (macOS only)

* First make sure to follow all the steps of part 2a.
* Install command-line support for Cocoapods using `sudo gem install cocoapods`.
* Update all pods using `cd ios; pod update`.
* If you're on an Apple Silicon chip, configure XCode to run using Rosetta 2 by navigating to the application, right-clicking it, selecting "Get Info", and ticking "Open using Rosetta".
* Open the project in XCode by starting XCode, selecting "Open a project or file", and opening the `ios` folder of this project.
* If you're on an Apple Silicon chip, start the iOS emulator using Rosetta 2. The easiest way to find it is to start it from XCode using XCode -> Open Developer Tool -> Simulator, then right-clicking it in the dock and selecting Options -> Show in Finder. From this executable the setting can be modified similar to how you just did it for XCode.
    * Make sure your iOS device has iOS 12.0 or greater installed, as that's the minimum supported version for this app.
* Once a simulated iOS device is running, it should show up in the list of target devices in Android Studio. At this point XCode can safely be closed.

In case of errors on iOS, it is advised to first try cleaning everything before attempting a fresh build:
```flutter clean; flutter upgrade; flutter build ios```

## Updating dependencies

* Open the `pubspec.yaml` file in Android Studio.
* If you have the Flutter Enhancement Suite installed, outdated dependencies will be automatically highlighted.
* Update all the version numbers to the latest versions and run `pub upgrade`.
* Make any required changes to the code.
* Test the new dependencies.
* Commit the changes to `pubspec.yaml`, to the code, and the file `pubspec.lock` all at once.
  Don't forget the `pubspec.lock` file, as that contains the actual version number with which you tested!

Note: sometimes it's necessary to run `flutter update-packages --force-upgrade` to force an update of the built-in Flutter dependencies.

## Taking screenshots

### Apple

To take iOS/iPadOS screenshots, use the following simulated devices:

* 6.7" - iPhone 13 Pro Max (optional)
* 6.5" - iPhone 11 Pro Max
* 5.5" - iPhone 8 Plus
* iPad Pro (12.9-inch) (3rd generation)
* iPad Pro (12.9-inch) (2nd generation)

The simulated devices' language should be set to "English (UK)", and the region to "Netherlands".

Before taking the screenshots, use the following command to make the status bar prettier (noon local time on the first day of CaDansa that year, make sure to update the date):

```shell
xcrun simctl status_bar booted override --time "2022-10-20T12:00:00+02:00" --cellularBars 4 --batteryLevel 100
```

repository: balfolk/cadansa-app

repo_name: balfolk/cadansa-app


text:
---
title: How do I delete a branch?
template: article.jade
---

Delete a local branch `feature`:

    git branch -d feature

This will fail if the branch is not merged. To delete the branch regardless:

    git branch -D feature

To delete a remote branch `feature` on remote `origin` (warning: There is no confirmation!):

    git push origin :feature

Note: `git-branch` documentation lists documentation for the option `-r` which works on remote *tracking* branches, not
branches on the remote; `git branch -D -r origin/feature` will delete the remote tracking branch `origin/feature`,
not the branch `feature` on remote `origin`. Pulling/fetching from the remote again will recreate that tracking branch.

To delete remote tracking branches that no longer exist on the remote:

    git fetch --prune

repository: dfang/gitfaq

repo_name: dfang/gitfaq


text:
sshd Ansible role
=========

Configures sshd and adds authorized keys for users who need SSH access

Role Variables
--------------

The main variable you need to adjust is `ssh_users`. This is the list of users
who need their keys added to the box. If you have another role that manages users,
then just set `ssh_users` to inherit from `users`.

For safety, this role only alters `sshd_config` if the authorized keys were
successfully added to the box.

This role also defaults the `wheel` group to having passwordless sudo so that if
you accidentally disable root login via ssh you won't be locked out of root.

Other Notes
------------

One gotcha: Ansible will convert unquoted `yes`/`no` values to `True`/`False`,
but `sshd_config` only accepts `yes`/`no` values. So just quote the Ansible
variables like this: `permit_root_login: "yes"`

Requirements
------------

Tested on CentOS 7.
Untested but will likely work on CentOS 6 and equivalent RHEL versions.

Example Playbook
----------------

    - hosts: servers
      roles:
        - { role: sshd,
              permit_root_login: "no",
              password_authentication: "no",
              challenge_response_authentication: "no",
              tags: ['sshd'] }

License
-------

MIT

Author Information
------------------

Jeff Widman<EMAIL_ADDRESS>

repository: jeffwidman/ansible-sshd

repo_name: jeffwidman/ansible-sshd


text:
# ECS deploy
ECS Deploy is a REST API server written in Go that can be used to deploy services on ECS from anywhere. It typically is executed as part of your deployment pipeline. Continuous Integration software (like Jenkins, CircleCI, Bitbucket or others) often don't have proper integration with ECS. This API server can be deployed on ECS and will be used to provide continuous deployment on ECS.

* Registers services in DynamoDB
* Creates ECR repository
* Creates necessary IAM roles
* Creates ALB target and listener rules
* Creates and updates ECS Services based on JSON input

## How to deploy

* Deploy the docker image as a service on ECS
  * See examples/ecs-deploy.tf for a terraform deploy script
    * This script creates an ALB with the same name as the ECS cluster
    * Adds the IAM policy from examples/iam-policy.json
    * Adds dynamodb table with history of deployments

## Environment variables

AWS Specific variables:

* AWS\_REGION=region                  # mandatory

Authentication variables;
* JWT\_SECRET=secret                   # mandatory
* DEPLOY\_PASSWORD=deploy              # mandatory
* DEVELOPER\_PASSWORD=developer        # mandatory

Service specific variables (those will be used when deploying services):
* AWS\_ACCOUNT\_ENV=staging
* PARAMSTORE\_ENABLED=yes
* PARAMSTORE\_PREFIX=mycompany
* PARAMSTORE\_KMS\_ARN=
* CLOUDWATCH\_LOGS\_ENABLED=yes
* CLOUDWATCH\_LOGS\_PREFIX=mycompany
* LOADBALANCER\_DOMAIN=mycompany.com

## License
Copyright 2017 in4it BVBA

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


text:
# <img src="/src/icon.png" height="30px"> EmptyFiles

[![Build status](https://ci.appveyor.com/api/projects/status/4mrhpal9rwtqajws/branch/master?svg=true)](https://ci.appveyor.com/project/SimonCropp/EmptyFiles)
[![NuGet Status](https://img.shields.io/nuget/v/EmptyFiles.svg?label=EmptyFiles)](https://www.nuget.org/packages/EmptyFiles/)

A collection of minimal binary files.

Support is available via a [Tidelift Subscription](https://tidelift.com/subscription/pkg/nuget-emptyfiles?utm_source=nuget-emptyfiles&utm_medium=referral&utm_campaign=enterprise).

toc

## NuGet package

 * https://nuget.org/packages/EmptyFiles/

## Files

All files: https://github.com/SimonCropp/EmptyFiles/tree/master/files

include: extensions

## Usage

### CreateFile

Creates a new empty file

snippet: CreateFile

Throws an exception if the extension is not known. There is also a `TryCreateFile` that will return false if the extension is not known.

Use the optional `useEmptyStringForTextFiles` to create a empty text file if the extension is text. The file will be UTF8 no BOM as per https://www.unicode.org/versions/Unicode5.0.0/ch02.pdf "Use of a BOM is neither required nor recommended for UTF-8".

### GetPathFor

Gets the path to an empty file for a given extension

snippet: GetPathFor

Throws an exception if the extension is not known. There is also a `TryGetPathFor` that will return false if the extension is not known.

### IsEmptyFile

Returns true if the target file is an empty file.

snippet: IsEmptyFile

### AllPaths

Enumerates all empty files

snippet: AllPaths

### UseFile

Use or replace a file

snippet: UseFile

### Extensions helper

#### IsText

https://github.com/sindresorhus/text-extensions/blob/master/text-extensions.json

snippet: IsText

#### AddTextExtension

snippet: AddTextExtension

#### RemoveTextExtension

snippet: RemoveTextExtension

## Security contact information

To report a security vulnerability, use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.

## Icon

[Hollow](https://thenounproject.com/term/hollow/51835/) designed by [Michael Senkow](https://thenounproject.com/mhsenkow/) from [The Noun Project](https://thenounproject.com).

repository: AaronDMarasco/EmptyFiles

repo_name: AaronDMarasco/EmptyFiles


text:
# Basicfuncode
This repository contains some basic beginner level projects.
## My calculator
This simple calculator app is built from tkinter library of python.

![](calculator.PNG)


text:
# Gossamer Specification

The aim of Gossamer is to allow automatic key/update trust in a way that can be
audited by independent third parties.

The basic idea of Gossamer is simple: Use verifiable data structures to create
a live snapshot of the current state of affairs for public keys and software
updates.

This requires that our protocol have a well-defined grammar, and a
straightforward flow to the components.

# Contents

 * [Gossamer Overview](Overview.md)
   * [Security Goals and Desired Properties](Overview.md#security-goals-and-desired-properties)
 * [The Gossamer Protocol](Protocol.md)
   * [Serialization Formats](Protocol.md#serialization-formats)
   * [The Super Provider](Protocol.md#the-super-provider)
   * [Actions and Validation Rules](Protocol.md#actions-and-validation-rules)
     * [AppendKey](Protocol.md#appendkey)
     * [RevokeKey](Protocol.md#revokekey)
     * [AppendUpdate](Protocol.md#appendupdate)
     * [RevokeUpdate](Protocol.md#revokeupdate)
     * [AttestUpdate](Protocol.md#attestupdate)

license: ISC

repository: paragonie/libgossamer

gha_language: PHP

repo_name: paragonie/libgossamer


text:
# AC_control
Arduino library for AC phase controller with peak detection.

This library controls AC power through phase cutting, with a synchronisation signal based on peak detection rather than zero crossing detection. It makes use of pin change interrupts (on PORTD) and Timer1.

Please note:
SYNC_PIN (receiving the peak transition pulse) must be conneted to a pin in PORTD, i.e. one of the digital pins 2-7.
GATE_PIN can be connected to any digital or analog pin (except A6/A7).
This library uses pin change interrupt on PORTD. This will cause problems if used with another library that tries to use the same interrupt vector (PCINT2_vect).
This library uses Timer1 and timer interrupts.
This library supports only one AC control unit per Arduino.
It is currently limited to 50 Hz AC (this is a code limitation).

Phase cutting is an AC control technique using a TRIAC to control how much of the waveform is let through to the device. The later in the wave the TRIAC is switched on, the less power is transferred to the connected device.

Schematics
-

In the ./schematics folder are the complete schematics and PCB development files.

The V1 PCB has been tested and was found to have some issues: the TRIAC was connected incorrectly, and an optocoupler footprint was wrong. These issues have been corrected in the development version in the root directory.

The schematic has been tested by reworking bits of the V1 PCB, but the redesigned PCB has not been tested as such.