circle | StackOverflow

### Answer rating: 292

In Python, with Matplotlib, how can a scatter plot with *empty* circles be plotted? The goal is to draw empty circles around *some* of the colored disks already plotted by `scatter()`

, so as to highlight them, ideally without having to redraw the colored circles.

I tried `facecolors=None`

, to no avail.

From the documentation for scatter:

```
Optional kwargs control the Collection properties; in particular:
edgecolors:
The string ‚Äònone‚Äô to plot faces with no outlines
facecolors:
The string ‚Äònone‚Äô to plot unfilled outlines
```

Try the following:

```
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(60)
y = np.random.randn(60)
plt.scatter(x, y, s=80, facecolors="none", edgecolors="r")
plt.show()
```

**Note:** For other types of plots see this post on the use of `markeredgecolor`

and `markerfacecolor`

.

In Python, with Matplotlib, how can a scatter plot with *empty* circles be plotted? The goal is to draw empty circles around *some* of the colored disks already plotted by `scatter()`

, so as to highlight them, ideally without having to redraw the colored circles.

I tried `facecolors=None`

, to no avail.

surprisingly I didn"t find a straight-forward description on how to draw a circle with matplotlib.pyplot (please no pylab) taking as input center (x,y) and radius r. I tried some variants of this:

```
import matplotlib.pyplot as plt
circle=plt.Circle((0,0),2)
# here must be something like circle.plot() or not?
plt.show()
```

... but still didn"t get it working.

You said you couldn‚Äôt get the golden spiral method to work and that‚Äôs a shame because it‚Äôs really, really good. I would like to give you a complete understanding of it so that maybe you can understand how to keep this away from being ‚Äúbunched up.‚Äù

So here‚Äôs a fast, non-random way to create a lattice that is approximately correct; as discussed above, no lattice will be perfect, but this may be good enough. It is compared to other methods e.g. at BendWavy.org but it just has a nice and pretty look as well as a guarantee about even spacing in the limit.

To understand this algorithm, I first invite you to look at the 2D sunflower spiral algorithm. This is based on the fact that the most irrational number is the golden ratio `(1 + sqrt(5))/2`

and if one emits points by the approach ‚Äústand at the center, turn a golden ratio of whole turns, then emit another point in that direction,‚Äù one naturally constructs a spiral which, as you get to higher and higher numbers of points, nevertheless refuses to have well-defined ‚Äòbars‚Äô that the points line up on.^{(Note 1.)}

The algorithm for even spacing on a disk is,

```
from numpy import pi, cos, sin, sqrt, arange
import matplotlib.pyplot as pp
num_pts = 100
indices = arange(0, num_pts, dtype=float) + 0.5
r = sqrt(indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
pp.scatter(r*cos(theta), r*sin(theta))
pp.show()
```

and it produces results that look like (n=100 and n=1000):

The key strange thing is the formula `r = sqrt(indices / num_pts)`

; how did I come to that one? ^{(Note 2.)}

Well, I am using the square root here because I want these to have even-area spacing around the disk. That is the same as saying that in the limit of large *N* I want a little region *R* ‚àà (*r*, *r* + d*r*), *Œò* ‚àà (*Œ∏*, *Œ∏* + d*Œ∏*) to contain a number of points proportional to its area, which is *r* d*r* d*Œ∏*. Now if we pretend that we are talking about a random variable here, this has a straightforward interpretation as saying that the joint probability density for (*R*, *Œò*) is just *c r* for some constant *c*. Normalization on the unit disk would then force *c* = 1/œÄ.

Now let me introduce a trick. It comes from probability theory where it‚Äôs known as sampling the inverse CDF: suppose you wanted to *generate* a random variable with a probability density *f*(*z*) and you have a random variable *U* ~ Uniform(0, 1), just like comes out of `random()`

in most programming languages. How do you do this?

- First, turn your density into a cumulative distribution function or CDF, which we will call
*F*(*z*). A CDF, remember, increases monotonically from 0 to 1 with derivative*f*(*z*). - Then calculate the CDF‚Äôs inverse function
*F*^{-1}(*z*). - You will find that
*Z*=*F*^{-1}(*U*) is distributed according to the target density.^{(Note 3).}

Now the golden-ratio spiral trick spaces the points out in a nicely even pattern for *Œ∏* so let‚Äôs integrate that out; for the unit disk we are left with *F*(*r*) = *r*^{2}. So the inverse function is *F*^{-1}(*u*) = *u*^{1/2}, and therefore we would generate random points on the disk in polar coordinates with `r = sqrt(random()); theta = 2 * pi * random()`

.

Now instead of *randomly* sampling this inverse function we‚Äôre *uniformly* sampling it, and the nice thing about uniform sampling is that our results about how points are spread out in the limit of large *N* will behave as if we had randomly sampled it. This combination is the trick. Instead of `random()`

we use `(arange(0, num_pts, dtype=float) + 0.5)/num_pts`

, so that, say, if we want to sample 10 points they are `r = 0.05, 0.15, 0.25, ... 0.95`

. We uniformly sample *r* to get equal-area spacing, and we use the sunflower increment to avoid awful ‚Äúbars‚Äù of points in the output.

The changes that we need to make to dot the sphere with points merely involve switching out the polar coordinates for spherical coordinates. The radial coordinate of course doesn"t enter into this because we"re on a unit sphere. To keep things a little more consistent here, even though I was trained as a physicist I"ll use mathematicians" coordinates where 0 ‚â§ *œÜ* ‚â§ œÄ is latitude coming down from the pole and 0 ‚â§ *Œ∏* ‚â§ 2œÄ is longitude. So the difference from above is that we are basically replacing the variable *r* with *œÜ*.

Our area element, which was *r* d*r* d*Œ∏*, now becomes the not-much-more-complicated sin(*œÜ*) d*œÜ* d*Œ∏*. So our joint density for uniform spacing is sin(*œÜ*)/4œÄ. Integrating out *Œ∏*, we find *f*(*œÜ*) = sin(*œÜ*)/2, thus *F*(*œÜ*) = (1 ‚àí cos(*œÜ*))/2. Inverting this we can see that a uniform random variable would look like acos(1 - 2 *u*), but we sample uniformly instead of randomly, so we instead use *œÜ*_{k} = acos(1 ‚àí 2 (*k* + 0.5)/*N*). And the rest of the algorithm is just projecting this onto the x, y, and z coordinates:

```
from numpy import pi, cos, sin, arccos, arange
import mpl_toolkits.mplot3d
import matplotlib.pyplot as pp
num_pts = 1000
indices = arange(0, num_pts, dtype=float) + 0.5
phi = arccos(1 - 2*indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
x, y, z = cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi);
pp.figure().add_subplot(111, projection="3d").scatter(x, y, z);
pp.show()
```

Again for n=100 and n=1000 the results look like:

I wanted to give a shout out to Martin Roberts‚Äôs blog. Note that above I created an offset of my indices by adding 0.5 to each index. This was just visually appealing to me, but it turns out that the choice of offset matters a lot and is not constant over the interval and can mean getting as much as 8% better accuracy in packing if chosen correctly. There should also be a way to get his R_{2} sequence to cover a sphere and it would be interesting to see if this also produced a nice even covering, perhaps as-is but perhaps needing to be, say, taken from only a half of the unit square cut diagonally or so and stretched around to get a circle.

Those ‚Äúbars‚Äù are formed by rational approximations to a number, and the best rational approximations to a number come from its continued fraction expression,

`z + 1/(n_1 + 1/(n_2 + 1/(n_3 + ...)))`

where`z`

is an integer and`n_1, n_2, n_3, ...`

is either a finite or infinite sequence of positive integers:`def continued_fraction(r): while r != 0: n = floor(r) yield n r = 1/(r - n)`

Since the fraction part

`1/(...)`

is always between zero and one, a large integer in the continued fraction allows for a particularly good rational approximation: ‚Äúone divided by something between 100 and 101‚Äù is better than ‚Äúone divided by something between 1 and 2.‚Äù The most irrational number is therefore the one which is`1 + 1/(1 + 1/(1 + ...))`

and has no particularly good rational approximations; one can solve*œÜ*= 1 + 1/*œÜ*by multiplying through by*œÜ*to get the formula for the golden ratio.For folks who are not so familiar with NumPy -- all of the functions are ‚Äúvectorized,‚Äù so that

`sqrt(array)`

is the same as what other languages might write`map(sqrt, array)`

. So this is a component-by-component`sqrt`

application. The same also holds for division by a scalar or addition with scalars -- those apply to all components in parallel.The proof is simple once you know that this is the result. If you ask what"s the probability that

*z*<*Z*<*z*+ d*z*, this is the same as asking what"s the probability that*z*<*F*^{-1}(*U*) <*z*+ d*z*, apply*F*to all three expressions noting that it is a monotonically increasing function, hence*F*(*z*) <*U*<*F*(*z*+ d*z*), expand the right hand side out to find*F*(*z*) +*f*(*z*) d*z*, and since*U*is uniform this probability is just*f*(*z*) d*z*as promised.

Python has no built-in encryption schemes, no. You also should take encrypted data storage serious; trivial encryption schemes that one developer understands to be insecure and a toy scheme may well be mistaken for a secure scheme by a less experienced developer. If you encrypt, encrypt properly.

You don‚Äôt need to do much work to implement a proper encryption scheme however. First of all, *don‚Äôt re-invent the cryptography wheel*, use a trusted cryptography library to handle this for you. For Python 3, that trusted library is `cryptography`

.

I also recommend that encryption and decryption applies to *bytes*; encode text messages to bytes first; `stringvalue.encode()`

encodes to UTF8, easily reverted again using `bytesvalue.decode()`

.

Last but not least, when encrypting and decrypting, we talk about *keys*, not passwords. A key should not be human memorable, it is something you store in a secret location but machine readable, whereas a password often can be human-readable and memorised. You *can* derive a key from a password, with a little care.

But for a web application or process running in a cluster without human attention to keep running it, you want to use a key. Passwords are for when only an end-user needs access to the specific information. Even then, you usually secure the application with a password, then exchange encrypted information using a key, perhaps one attached to the user account.

The `cryptography`

library includes the Fernet recipe, a best-practices recipe for using cryptography. Fernet is an open standard,
with ready implementations in a wide range of programming languages and it packages AES CBC encryption for you with version information, a timestamp and an HMAC signature to prevent message tampering.

Fernet makes it very easy to encrypt and decrypt messages *and* keep you secure. It is the ideal method for encrypting data with a secret.

I recommend you use `Fernet.generate_key()`

to generate a secure key. You can use a password too (next section), but a full 32-byte secret key (16 bytes to encrypt with, plus another 16 for the signature) is going to be more secure than most passwords you could think of.

The key that Fernet generates is a `bytes`

object with URL and file safe base64 characters, so printable:

```
from cryptography.fernet import Fernet
key = Fernet.generate_key() # store in a secure location
print("Key:", key.decode())
```

To encrypt or decrypt messages, create a `Fernet()`

instance with the given key, and call the `Fernet.encrypt()`

or `Fernet.decrypt()`

, both the plaintext message to encrypt and the encrypted token are `bytes`

objects.

`encrypt()`

and `decrypt()`

functions would look like:

```
from cryptography.fernet import Fernet
def encrypt(message: bytes, key: bytes) -> bytes:
return Fernet(key).encrypt(message)
def decrypt(token: bytes, key: bytes) -> bytes:
return Fernet(key).decrypt(token)
```

Demo:

```
>>> key = Fernet.generate_key()
>>> print(key.decode())
GZWKEhHGNopxRdOHS4H4IyKhLQ8lwnyU7vRLrM3sebY=
>>> message = "John Doe"
>>> encrypt(message.encode(), key)
"gAAAAABciT3pFbbSihD_HZBZ8kqfAj94UhknamBuirZWKivWOukgKQ03qE2mcuvpuwCSuZ-X_Xkud0uWQLZ5e-aOwLC0Ccnepg=="
>>> token = _
>>> decrypt(token, key).decode()
"John Doe"
```

You can use a password instead of a secret key, provided you use a strong key derivation method. You do then have to include the salt and the HMAC iteration count in the message, so the encrypted value is not Fernet-compatible anymore without first separating salt, count and Fernet token:

```
import secrets
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
backend = default_backend()
iterations = 100_000
def _derive_key(password: bytes, salt: bytes, iterations: int = iterations) -> bytes:
"""Derive a secret key from a given password and salt"""
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(), length=32, salt=salt,
iterations=iterations, backend=backend)
return b64e(kdf.derive(password))
def password_encrypt(message: bytes, password: str, iterations: int = iterations) -> bytes:
salt = secrets.token_bytes(16)
key = _derive_key(password.encode(), salt, iterations)
return b64e(
b"%b%b%b" % (
salt,
iterations.to_bytes(4, "big"),
b64d(Fernet(key).encrypt(message)),
)
)
def password_decrypt(token: bytes, password: str) -> bytes:
decoded = b64d(token)
salt, iter, token = decoded[:16], decoded[16:20], b64e(decoded[20:])
iterations = int.from_bytes(iter, "big")
key = _derive_key(password.encode(), salt, iterations)
return Fernet(key).decrypt(token)
```

Demo:

```
>>> message = "John Doe"
>>> password = "mypass"
>>> password_encrypt(message.encode(), password)
b"9Ljs-w8IRM3XT1NDBbSBuQABhqCAAAAAAFyJdhiCPXms2vQHO7o81xZJn5r8_PAtro8Qpw48kdKrq4vt-551BCUbcErb_GyYRz8SVsu8hxTXvvKOn9QdewRGDfwx"
>>> token = _
>>> password_decrypt(token, password).decode()
"John Doe"
```

Including the salt in the output makes it possible to use a random salt value, which in turn ensures the encrypted output is guaranteed to be fully random regardless of password reuse or message repetition. Including the iteration count ensures that you can adjust for CPU performance increases over time without losing the ability to decrypt older messages.

A password alone *can* be as safe as a Fernet 32-byte random key, provided you generate a properly random password from a similar size pool. 32 bytes gives you 256 ^ 32 number of keys, so if you use an alphabet of 74 characters (26 upper, 26 lower, 10 digits and 12 possible symbols), then your password should be at least `math.ceil(math.log(256 ** 32, 74))`

== 42 characters long. However, a well-selected larger number of HMAC iterations can mitigate the lack of entropy somewhat as this makes it much more expensive for an attacker to brute force their way in.

Just know that choosing a shorter but still reasonably secure password won‚Äôt cripple this scheme, it just reduces the number of possible values a brute-force attacker would have to search through; make sure to pick a strong enough password for your security requirements.

An alternative is *not to encrypt*. Don"t be tempted to just use a low-security cipher, or a home-spun implementation of, say Vignere. There is no security in these approaches, but may give an inexperienced developer that is given the task to maintain your code in future the illusion of security, which is worse than no security at all.

If all you need is obscurity, just base64 the data; for URL-safe requirements, the `base64.urlsafe_b64encode()`

function is fine. Don"t use a password here, just encode and you are done. At most, add some compression (like `zlib`

):

```
import zlib
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d
def obscure(data: bytes) -> bytes:
return b64e(zlib.compress(data, 9))
def unobscure(obscured: bytes) -> bytes:
return zlib.decompress(b64d(obscured))
```

This turns `b"Hello world!"`

into `b"eNrzSM3JyVcozy_KSVEEAB0JBF4="`

.

If all you need is a way to make sure that the data can be trusted to be *unaltered* after having been sent to an untrusted client and received back, then you want to sign the data, you can use the `hmac`

library for this with SHA1 (still considered secure for HMAC signing) or better:

```
import hmac
import hashlib
def sign(data: bytes, key: bytes, algorithm=hashlib.sha256) -> bytes:
assert len(key) >= algorithm().digest_size, (
"Key must be at least as long as the digest size of the "
"hashing algorithm"
)
return hmac.new(key, data, algorithm).digest()
def verify(signature: bytes, data: bytes, key: bytes, algorithm=hashlib.sha256) -> bytes:
expected = sign(data, key, algorithm)
return hmac.compare_digest(expected, signature)
```

Use this to sign data, then attach the signature with the data and send that to the client. When you receive the data back, split data and signature and verify. I"ve set the default algorithm to SHA256, so you"ll need a 32-byte key:

```
key = secrets.token_bytes(32)
```

You may want to look at the `itsdangerous`

library, which packages this all up with serialisation and de-serialisation in various formats.

Fernet builds on AEC-CBC with a HMAC signature to ensure integrity of the encrypted data; a malicious attacker can"t feed your system nonsense data to keep your service busy running in circles with bad input, because the ciphertext is signed.

The Galois / Counter mode block cipher produces ciphertext and a *tag* to serve the same purpose, so can be used to serve the same purposes. The downside is that unlike Fernet there is no easy-to-use one-size-fits-all recipe to reuse on other platforms. AES-GCM also doesn"t use padding, so this encryption ciphertext matches the length of the input message (whereas Fernet / AES-CBC encrypts messages to blocks of fixed length, obscuring the message length somewhat).

AES256-GCM takes the usual 32 byte secret as a key:

```
key = secrets.token_bytes(32)
```

then use

```
import binascii, time
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.exceptions import InvalidTag
backend = default_backend()
def aes_gcm_encrypt(message: bytes, key: bytes) -> bytes:
current_time = int(time.time()).to_bytes(8, "big")
algorithm = algorithms.AES(key)
iv = secrets.token_bytes(algorithm.block_size // 8)
cipher = Cipher(algorithm, modes.GCM(iv), backend=backend)
encryptor = cipher.encryptor()
encryptor.authenticate_additional_data(current_time)
ciphertext = encryptor.update(message) + encryptor.finalize()
return b64e(current_time + iv + ciphertext + encryptor.tag)
def aes_gcm_decrypt(token: bytes, key: bytes, ttl=None) -> bytes:
algorithm = algorithms.AES(key)
try:
data = b64d(token)
except (TypeError, binascii.Error):
raise InvalidToken
timestamp, iv, tag = data[:8], data[8:algorithm.block_size // 8 + 8], data[-16:]
if ttl is not None:
current_time = int(time.time())
time_encrypted, = int.from_bytes(data[:8], "big")
if time_encrypted + ttl < current_time or current_time + 60 < time_encrypted:
# too old or created well before our current time + 1 h to account for clock skew
raise InvalidToken
cipher = Cipher(algorithm, modes.GCM(iv, tag), backend=backend)
decryptor = cipher.decryptor()
decryptor.authenticate_additional_data(timestamp)
ciphertext = data[8 + len(iv):-16]
return decryptor.update(ciphertext) + decryptor.finalize()
```

I"ve included a timestamp to support the same time-to-live use-cases that Fernet supports.

This is the approach that All –Ü—ï V–∞–∏—ñ—Çy follows, albeit incorrectly. This is the `cryptography`

version, but note that I *include the IV in the ciphertext*, it should not be stored as a global (reusing an IV weakens the security of the key, and storing it as a module global means it"ll be re-generated the next Python invocation, rendering all ciphertext undecryptable):

```
import secrets
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
backend = default_backend()
def aes_cfb_encrypt(message, key):
algorithm = algorithms.AES(key)
iv = secrets.token_bytes(algorithm.block_size // 8)
cipher = Cipher(algorithm, modes.CFB(iv), backend=backend)
encryptor = cipher.encryptor()
ciphertext = encryptor.update(message) + encryptor.finalize()
return b64e(iv + ciphertext)
def aes_cfb_decrypt(ciphertext, key):
iv_ciphertext = b64d(ciphertext)
algorithm = algorithms.AES(key)
size = algorithm.block_size // 8
iv, encrypted = iv_ciphertext[:size], iv_ciphertext[size:]
cipher = Cipher(algorithm, modes.CFB(iv), backend=backend)
decryptor = cipher.decryptor()
return decryptor.update(encrypted) + decryptor.finalize()
```

This lacks the added armoring of an HMAC signature and there is no timestamp; you‚Äôd have to add those yourself.

The above also illustrates how easy it is to combine basic cryptography building blocks incorrectly; All –Ü—ï V–∞–∏—ñ—Çy‚Äòs incorrect handling of the IV value can lead to a data breach or all encrypted messages being unreadable because the IV is lost. Using Fernet instead protects you from such mistakes.

If you previously implemented AES ECB encryption and need to still support this in Python 3, you can do so still with `cryptography`

too. **The same caveats apply, ECB is not secure enough for real-life applications**. Re-implementing that answer for Python 3, adding automatic handling of padding:

```
from base64 import urlsafe_b64encode as b64e, urlsafe_b64decode as b64d
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
backend = default_backend()
def aes_ecb_encrypt(message, key):
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
encryptor = cipher.encryptor()
padder = padding.PKCS7(cipher.algorithm.block_size).padder()
padded = padder.update(msg_text.encode()) + padder.finalize()
return b64e(encryptor.update(padded) + encryptor.finalize())
def aes_ecb_decrypt(ciphertext, key):
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
decryptor = cipher.decryptor()
unpadder = padding.PKCS7(cipher.algorithm.block_size).unpadder()
padded = decryptor.update(b64d(ciphertext)) + decryptor.finalize()
return unpadder.update(padded) + unpadder.finalize()
```

Again, this lacks the HMAC signature, and you shouldn‚Äôt use ECB anyway. The above is there merely to illustrate that `cryptography`

can handle the common cryptographic building blocks, even the ones you shouldn‚Äôt actually use.

```
import matplotlib.pyplot as plt
circle1 = plt.Circle((0, 0), 0.2, color="r")
plt.gca().add_patch(circle1)
```

A quick condensed version of the accepted answer, to quickly plug a circle into an existing plot. Refer to the accepted answer and other answers to understand the details.

By the way:

`gca()`

means Get Current Axis

There is a picture show all markers" name and description, i hope it will help you.

```
import matplotlib.pylab as plt
markers = [".",",","o","v","^","<",">","1","2","3","4","8","s","p","P","*","h","H","+","x","X","D","d","|","_"]
descriptions = ["point", "pixel", "circle", "triangle_down", "triangle_up","triangle_left",
"triangle_right", "tri_down", "tri_up", "tri_left", "tri_right", "octagon",
"square", "pentagon", "plus (filled)","star", "hexagon1", "hexagon2", "plus",
"x", "x (filled)","diamond", "thin_diamond", "vline", "hline"]
x=[]
y=[]
for i in range(5):
for j in range(5):
x.append(i)
y.append(j)
plt.figure(figsize=(8, 8))
for i,j,m,l in zip(x,y,markers,descriptions):
plt.scatter(i,j,marker=m)
plt.text(i-0.15,j+0.15,s=m+" : "+l)
plt.axis([-0.1,4.8,-0.1,4.5])
plt.axis("off")
plt.tight_layout()
plt.show()
```

By definition, `isdecimal()`

‚äÜ `isdigit()`

‚äÜ `isnumeric()`

. That is, if a string is `decimal`

, then it"ll also be `digit`

and `numeric`

.

Therefore, given a string `s`

and test it with those three methods, there"ll only be 4 types of results.

```
+-------------+-----------+-------------+----------------------------------+
| isdecimal() | isdigit() | isnumeric() | Example |
+-------------+-----------+-------------+----------------------------------+
| True | True | True | "038", "‡©¶‡©©‡©Æ", "ÔºêÔºìÔºò" |
| False | True | True | "‚Å∞¬≥‚Å∏", "üÑÄ‚íä‚íè", "‚ì™‚ë¢‚ëß" |
| False | False | True | "‚Üâ‚Öõ‚Öò", "‚Ö†‚Ö¢‚Öß", "‚ë©‚ë¨„äø", "Â£πË≤≥ÂèÉ" |
| False | False | False | "abc", "38.0", "-38" |
+-------------+-----------+-------------+----------------------------------+
```

**1. Some examples of characters isdecimal()==True**

(thus `isdigit()==True`

and `isnumeric()==True`

)

```
"0123456789" DIGIT ZERO~NINE
"Ÿ†Ÿ°Ÿ¢Ÿ£Ÿ§Ÿ•Ÿ¶ŸßŸ®Ÿ©" ARABIC-INDIC DIGIT ZERO~NINE
"‡•¶‡•ß‡•®‡•©‡•™‡•´‡•¨‡•≠‡•Æ‡•Ø" DEVANAGARI DIGIT ZERO~NINE
"‡ß¶‡ßß‡ß®‡ß©‡ß™‡ß´‡ß¨‡ß≠‡ßÆ‡ßØ" BENGALI DIGIT ZERO~NINE
"‡©¶‡©ß‡©®‡©©‡©™‡©´‡©¨‡©≠‡©Æ‡©Ø" GURMUKHI DIGIT ZERO~NINE
"‡´¶‡´ß‡´®‡´©‡´™‡´´‡´¨‡´≠‡´Æ‡´Ø" GUJARATI DIGIT ZERO~NINE
"‡≠¶‡≠ß‡≠®‡≠©‡≠™‡≠´‡≠¨‡≠≠‡≠Æ‡≠Ø" ORIYA DIGIT ZERO~NINE
"‡Ø¶‡Øß‡Ø®‡Ø©‡Ø™‡Ø´‡Ø¨‡Ø≠‡ØÆ‡ØØ" TAMIL DIGIT ZERO~NINE
"‡±¶‡±ß‡±®‡±©‡±™‡±´‡±¨‡±≠‡±Æ‡±Ø" TELUGU DIGIT ZERO~NINE
"‡≥¶‡≥ß‡≥®‡≥©‡≥™‡≥´‡≥¨‡≥≠‡≥Æ‡≥Ø" KANNADA DIGIT ZERO~NINE
"‡µ¶‡µß‡µ®‡µ©‡µ™‡µ´‡µ¨‡µ≠‡µÆ‡µØ" MALAYALAM DIGIT ZERO~NINE
"‡πê‡πë‡πí‡πì‡πî‡πï‡πñ‡πó‡πò‡πô" THAI DIGIT ZERO~NINE
"‡ªê‡ªë‡ªí‡ªì‡ªî‡ªï‡ªñ‡ªó‡ªò‡ªô" LAO DIGIT ZERO~NINE
"‡º†‡º°‡º¢‡º£‡º§‡º•‡º¶‡ºß‡º®‡º©" TIBETAN DIGIT ZERO~NINE
"·ÅÄ·ÅÅ·ÅÇ·ÅÉ·ÅÑ·ÅÖ·ÅÜ·Åá·Åà·Åâ" MYANMAR DIGIT ZERO~NINE
"·ü†·ü°·ü¢·ü£·ü§·ü•·ü¶·üß·ü®·ü©" KHMER DIGIT ZERO~NINE
"ÔºêÔºëÔºíÔºìÔºîÔºïÔºñÔºóÔºòÔºô" FULLWIDTH DIGIT ZERO~NINE
"ùüéùüèùüêùüëùüíùüìùüîùüïùüñùüó" MATHEMATICAL BOLD DIGIT ZERO~NINE
"ùüòùüôùüöùüõùüúùüùùüûùüüùü†ùü°" MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO~NINE
"ùü¢ùü£ùü§ùü•ùü¶ùüßùü®ùü©ùü™ùü´" MATHEMATICAL SANS-SERIF DIGIT ZERO~NINE
"ùü¨ùü≠ùüÆùüØùü∞ùü±ùü≤ùü≥ùü¥ùüµ" MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO~NINE
"ùü∂ùü∑ùü∏ùüπùü∫ùüªùüºùüΩùüæùüø" MATHEMATICAL MONOSPACE DIGIT ZERO~NINE
```

**2. Some examples of characters isdecimal()==False but isdigit()==True**

(thus `isnumeric()==True`

)

```
"‚Å∞¬π¬≤¬≥‚Å¥‚Åµ‚Å∂‚Å∑‚Å∏‚Åπ" SUPERSCRIPT ZERO~NINE
"‚ÇÄ‚ÇÅ‚ÇÇ‚ÇÉ‚ÇÑ‚ÇÖ‚ÇÜ‚Çá‚Çà‚Çâ" SUBSCRIPT ZERO~NINE
"üÑÄ‚íà‚íâ‚íä‚íã‚íå‚íç‚íé‚íè‚íê" DIGIT ZERO~NINE FULL STOP
"üÑÅüÑÇüÑÉüÑÑüÑÖüÑÜüÑáüÑàüÑâüÑä" DIGIT ZERO~NINE COMMA
"‚ì™‚ë†‚ë°‚ë¢‚ë£‚ë§‚ë•‚ë¶‚ëß‚ë®" CIRCLED DIGIT ZERO~NINE
"‚ìø‚ù∂‚ù∑‚ù∏‚ùπ‚ù∫‚ùª‚ùº‚ùΩ‚ùæ" NEGATIVE CIRCLED DIGIT ZERO~NINE
"‚ë¥‚ëµ‚ë∂‚ë∑‚ë∏‚ëπ‚ë∫‚ëª‚ëº" PARENTHESIZED DIGIT ONE~NINE
"‚ûÄ‚ûÅ‚ûÇ‚ûÉ‚ûÑ‚ûÖ‚ûÜ‚ûá‚ûà" DINGBAT CIRCLED SANS-SERIF DIGIT ONE~NINE
"‚ìµ‚ì∂‚ì∑‚ì∏‚ìπ‚ì∫‚ìª‚ìº‚ìΩ" DOUBLE CIRCLED DIGIT ONE~NINE
"‚ûä‚ûã‚ûå‚ûç‚ûé‚ûè‚ûê‚ûë‚ûí" DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE~NINE
"·ç©·ç™·ç´·ç¨·ç≠·çÆ·çØ·ç∞·ç±" ETHIOPIC DIGIT ONE~NINE
```

**3. Some examples of characters isdecimal()==False and isdigit()==False but isnumeric()==True**

```
"¬Ω‚Öì¬º‚Öï‚Öô‚Öê‚Öõ‚Öë‚Öí‚Öî¬æ‚Öñ‚Öó‚Öò‚Öö‚Öú‚Öù‚Öû‚Öü‚Üâ" VULGAR FRACTION
"‡ß¥‡ßµ‡ß∂‡ß∑‡ß∏‡ßπ" BENGALI CURRENCY NUMERATOR
"‡Ø∞‡Ø±‡Ø≤" TAMIL NUMBER TEN, ONE HUNDRED, ONE THOUSAND
"‡±∏‡±π‡±∫‡±ª‡±º‡±Ω‡±æ" TELUGU FRACTION DIGIT
"‡µ∞‡µ±‡µ≤‡µ≥‡µ¥‡µµ" MALAYALAM NUMBER, MALAYALAM FRACTION
"‡º≥‡º™‡º´‡º¨‡º≠‡ºÆ‡ºØ‡º∞‡º±‡º≤" TIBETAN DIGIT HALF ZERO~NINE
"·ç≤·ç≥·ç¥·çµ·ç∂·ç∑·ç∏·çπ·ç∫·çª·çº" ETHIOPIC NUMBER TEN~NINETY, HUNDRED, TEN THOUSAND
"·ü∞·ü±·ü≤·ü≥·ü¥·üµ·ü∂·ü∑·ü∏·üπ" KHMER SYMBOL LEK ATTAK
"‚Ö†‚Ö°‚Ö¢‚Ö£‚Ö§‚Ö•‚Ö¶‚Öß‚Ö®‚Ö©‚Ö™‚Ö´‚Ö¨‚Ö≠‚ÖÆ‚ÖØ" ROMAN NUMERAL
"‚Ö∞‚Ö±‚Ö≤‚Ö≥‚Ö¥‚Öµ‚Ö∂‚Ö∑‚Ö∏‚Öπ‚Ö∫‚Öª‚Öº‚ÖΩ‚Öæ‚Öø" SMALL ROMAN NUMERAL
"‚ÜÄ‚ÜÅ‚ÜÇ‚ÜÖ‚ÜÜ" ROMAN NUMERAL
"‚ë©‚ë™‚ë´‚ë¨‚ë≠‚ëÆ‚ëØ‚ë∞‚ë±‚ë≤‚ë≥„âë„âí„âì„âî„âï„âñ„âó„âò„âô„âö„âõ„âú„âù„âû„âü„ä±„ä≤„ä≥„ä¥„äµ„ä∂„ä∑„ä∏„äπ„ä∫„äª„äº„äΩ„äæ„äø" CIRCLED NUMBER TEN~FIFTY
"„âà„ââ„âä„âã„âå„âç„âé„âè" CIRCLED NUMBER TEN~EIGHTY ON BLACK SQUARE
"‚ëΩ‚ëæ‚ëø‚íÄ‚íÅ‚íÇ‚íÉ‚íÑ‚íÖ‚íÜ‚íá" PARENTHESIZED NUMBER TEN~TWENTY
"‚íë‚íí‚íì‚íî‚íï‚íñ‚íó‚íò‚íô‚íö‚íõ" NUMBER TEN~TWENTY FULL STOP
"‚ì´‚ì¨‚ì≠‚ìÆ‚ìØ‚ì∞‚ì±‚ì≤‚ì≥‚ì¥" NEGATIVE CIRCLED NUMBER ELEVEN
"‚ìæ‚ûâ‚ùø‚ûì" various styles of CIRCLED NUMBER TEN
"üÑå" DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
"„Äá" IDEOGRAPHIC NUMBER ZERO
"„Ä°„Ä¢„Ä£„Ä§„Ä•„Ä¶„Äß„Ä®„Ä©„Ä∏„Äπ„Ä∫" HANGZHOU NUMERAL ONE~TEN, TWENTY, THIRTY
"„Üí„Üì„Üî„Üï" IDEOGRAPHIC ANNOTATION ONE~FOUR MARK
"„à†„à°„à¢„à£„à§„à•„à¶„àß„à®„à©" PARENTHESIZED IDEOGRAPH ONE~TEN
"„äÄ„äÅ„äÇ„äÉ„äÑ„äÖ„äÜ„äá„äà„äâ" CIRCLED IDEOGRAPH ONE~TEN
"‰∏Ä‰∫å‰∏âÂõõ‰∫îÂÖ≠‰∏ÉÂÖ´‰πùÂçÅÂ£πË≤≥ÂèÉËÇÜ‰ºçÈô∏ÊüíÊçåÁéñÊãæÈõ∂ÁôæÂçÉËê¨ÂÑÑÂÖÜÂºêË≤ÆË¥∞„íÉ„≠çÊºÜ‰ªÄ„êÖÈôåÈò°‰Ω∞‰ªü‰∏á‰∫øÂπ∫ÂÖ©„†™‰∫ñÂçÑÂçÖÂçåÂªæÂªø" CJK UNIFIED IDEOGRAPH
"Ô•´Ô•≥Ô•∏Ô¶≤ÔßëÔßìÔßΩ" CJK COMPATIBILITY IDEOGRAPH
"êÑáêÑàêÑâêÑäêÑãêÑåêÑçêÑéêÑèêÑêêÑëêÑíêÑìêÑîêÑïêÑñêÑóêÑò" AEGEAN NUMBER ONE~NINE, TEN~NINETY
"êÑôêÑöêÑõêÑúêÑùêÑûêÑüêÑ†êÑ°êÑ¢êÑ£êÑ§êÑ•êÑ¶êÑßêÑ®êÑ©êÑ™" AEGEAN NUMBER ONE~NINE HUNDRED, ONE~NINE THOUSAND
"êÑ¨êÑ≠êÑÆêÑØêÑ∞êÑ±êÑ≤êÑ≥" AEGEAN NUMBER TEN~NINETY THOUSAND
"êÖÄêÖÅêÖÇêÖÉêÖÜêÖáêÖàêÖâêÖäêÖãêÖåêÖçêÖéêÖèêÖêêÖëêÖíêÖìêÖîêÖïêÖñêÖóêÖòêÖôêÖöêÖõêÖúêÖùêÖûêÖüêÖ†êÖ°êÖ¢êÖ£êÖ§êÖ•êÖ¶êÖßêÖ®êÖ©êÖ™êÖ´êÖ¨êÖ≠êÖÆêÖØêÖ∞êÖ±êÖ≤êÖ≥êÖ¥" GREEK ACROPHONIC ATTIC
"ùç†ùç°ùç¢ùç£ùç§ùç•ùç¶ùçßùç®" COUNTING ROD UNIT DIGIT ONE~NINE
"ùç©ùç™ùç´ùç¨ùç≠ùçÆùçØùç∞ùç±" COUNTING ROD TENS DIGIT ONE~NINE
```

@Jan Kuiken"s answer is certainly well-thought and thorough, but there are some caveats:

- it does not work in all cases
- it requires a fair amount of extra code
- it may vary considerably from one plot to the next

A much simpler approach is to annotate the last point of each plot. The point can also be circled, for emphasis. This can be accomplished with one extra line:

```
from matplotlib import pyplot as plt
for i, (x, y) in enumerate(samples):
plt.plot(x, y)
plt.text(x[-1], y[-1], "sample {i}".format(i=i))
```

A variant would be to use `ax.annotate`

.

If you are not into long explanations, see Paolo Bergantino‚Äôs answer.

To understand decorators, you must first understand that functions are objects in Python. This has important consequences. Let‚Äôs see why with a simple example :

```
def shout(word="yes"):
return word.capitalize()+"!"
print(shout())
# outputs : "Yes!"
# As an object, you can assign the function to a variable like any other object
scream = shout
# Notice we don"t use parentheses: we are not calling the function,
# we are putting the function "shout" into the variable "scream".
# It means you can then call "shout" from "scream":
print(scream())
# outputs : "Yes!"
# More than that, it means you can remove the old name "shout",
#¬†and the function will still be accessible from "scream"
del shout
try:
print(shout())
except NameError as e:
print(e)
#outputs: "name "shout" is not defined"
print(scream())
# outputs: "Yes!"
```

Keep this in mind. We‚Äôll circle back to it shortly.

Another interesting property of Python functions is they can be defined inside another function!

```
def talk():
# You can define a function on the fly in "talk" ...
def whisper(word="yes"):
return word.lower()+"..."
# ... and use it right away!
print(whisper())
# You call "talk", that defines "whisper" EVERY TIME you call it, then
# "whisper" is called in "talk".
talk()
# outputs:
# "yes..."
# But "whisper" DOES NOT EXIST outside "talk":
try:
print(whisper())
except NameError as e:
print(e)
#outputs : "name "whisper" is not defined"*
#Python"s functions are objects
```

Okay, still here? Now the fun part...

You‚Äôve seen that functions are objects. Therefore, functions:

- can be assigned to a variable
- can be defined in another function

That means that **a function can return another function**.

```
def getTalk(kind="shout"):
# We define functions on the fly
def shout(word="yes"):
return word.capitalize()+"!"
def whisper(word="yes") :
return word.lower()+"..."
# Then we return one of them
if kind == "shout":
# We don"t use "()", we are not calling the function,
# we are returning the function object
return shout
else:
return whisper
# How do you use this strange beast?
# Get the function and assign it to a variable
talk = getTalk()
# You can see that "talk" is here a function object:
print(talk)
#outputs : <function shout at 0xb7ea817c>
# The object is the one returned by the function:
print(talk())
#outputs : Yes!
# And you can even use it directly if you feel wild:
print(getTalk("whisper")())
#outputs : yes...
```

There‚Äôs more!

If you can `return`

a function, you can pass one as a parameter:

```
def doSomethingBefore(func):
print("I do something before then I call the function you gave me")
print(func())
doSomethingBefore(scream)
#outputs:
#I do something before then I call the function you gave me
#Yes!
```

Well, you just have everything needed to understand decorators. You see, decorators are ‚Äúwrappers‚Äù, which means that **they let you execute code before and after the function they decorate** without modifying the function itself.

How you‚Äôd do it manually:

```
# A decorator is a function that expects ANOTHER function as parameter
def my_shiny_new_decorator(a_function_to_decorate):
# Inside, the decorator defines a function on the fly: the wrapper.
# This function is going to be wrapped around the original function
# so it can execute code before and after it.
def the_wrapper_around_the_original_function():
# Put here the code you want to be executed BEFORE the original function is called
print("Before the function runs")
# Call the function here (using parentheses)
a_function_to_decorate()
# Put here the code you want to be executed AFTER the original function is called
print("After the function runs")
# At this point, "a_function_to_decorate" HAS NEVER BEEN EXECUTED.
# We return the wrapper function we have just created.
# The wrapper contains the function and the code to execute before and after. It‚Äôs ready to use!
return the_wrapper_around_the_original_function
# Now imagine you create a function you don"t want to ever touch again.
def a_stand_alone_function():
print("I am a stand alone function, don"t you dare modify me")
a_stand_alone_function()
#outputs: I am a stand alone function, don"t you dare modify me
# Well, you can decorate it to extend its behavior.
# Just pass it to the decorator, it will wrap it dynamically in
# any code you want and return you a new function ready to be used:
a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#outputs:
#Before the function runs
#I am a stand alone function, don"t you dare modify me
#After the function runs
```

Now, you probably want that every time you call `a_stand_alone_function`

, `a_stand_alone_function_decorated`

is called instead. That‚Äôs easy, just overwrite `a_stand_alone_function`

with the function returned by `my_shiny_new_decorator`

:

```
a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()
#outputs:
#Before the function runs
#I am a stand alone function, don"t you dare modify me
#After the function runs
# That‚Äôs EXACTLY what decorators do!
```

The previous example, using the decorator syntax:

```
@my_shiny_new_decorator
def another_stand_alone_function():
print("Leave me alone")
another_stand_alone_function()
#outputs:
#Before the function runs
#Leave me alone
#After the function runs
```

Yes, that‚Äôs all, it‚Äôs that simple. `@decorator`

is just a shortcut to:

```
another_stand_alone_function = my_shiny_new_decorator(another_stand_alone_function)
```

Decorators are just a pythonic variant of the decorator design pattern. There are several classic design patterns embedded in Python to ease development (like iterators).

Of course, you can accumulate decorators:

```
def bread(func):
def wrapper():
print("</"""""">")
func()
print("<\______/>")
return wrapper
def ingredients(func):
def wrapper():
print("#tomatoes#")
func()
print("~salad~")
return wrapper
def sandwich(food="--ham--"):
print(food)
sandwich()
#outputs: --ham--
sandwich = bread(ingredients(sandwich))
sandwich()
#outputs:
#</"""""">
# #tomatoes#
# --ham--
# ~salad~
#<\______/>
```

Using the Python decorator syntax:

```
@bread
@ingredients
def sandwich(food="--ham--"):
print(food)
sandwich()
#outputs:
#</"""""">
# #tomatoes#
# --ham--
# ~salad~
#<\______/>
```

The order you set the decorators MATTERS:

```
@ingredients
@bread
def strange_sandwich(food="--ham--"):
print(food)
strange_sandwich()
#outputs:
##tomatoes#
#</"""""">
# --ham--
#<\______/>
# ~salad~
```

As a conclusion, you can easily see how to answer the question:

```
# The decorator to make it bold
def makebold(fn):
# The new function the decorator returns
def wrapper():
# Insertion of some code before and after
return "<b>" + fn() + "</b>"
return wrapper
# The decorator to make it italic
def makeitalic(fn):
# The new function the decorator returns
def wrapper():
# Insertion of some code before and after
return "<i>" + fn() + "</i>"
return wrapper
@makebold
@makeitalic
def say():
return "hello"
print(say())
#outputs: <b><i>hello</i></b>
# This is the exact equivalent to
def say():
return "hello"
say = makebold(makeitalic(say))
print(say())
#outputs: <b><i>hello</i></b>
```

You can now just leave happy, or burn your brain a little bit more and see advanced uses of decorators.

```
# It‚Äôs not black magic, you just have to let the wrapper
# pass the argument:
def a_decorator_passing_arguments(function_to_decorate):
def a_wrapper_accepting_arguments(arg1, arg2):
print("I got args! Look: {0}, {1}".format(arg1, arg2))
function_to_decorate(arg1, arg2)
return a_wrapper_accepting_arguments
# Since when you are calling the function returned by the decorator, you are
# calling the wrapper, passing arguments to the wrapper will let it pass them to
# the decorated function
@a_decorator_passing_arguments
def print_full_name(first_name, last_name):
print("My name is {0} {1}".format(first_name, last_name))
print_full_name("Peter", "Venkman")
# outputs:
#I got args! Look: Peter Venkman
#My name is Peter Venkman
```

One nifty thing about Python is that methods and functions are really the same. The only difference is that methods expect that their first argument is a reference to the current object (`self`

).

That means you can build a decorator for methods the same way! Just remember to take `self`

into consideration:

```
def method_friendly_decorator(method_to_decorate):
def wrapper(self, lie):
lie = lie - 3 # very friendly, decrease age even more :-)
return method_to_decorate(self, lie)
return wrapper
class Lucy(object):
def __init__(self):
self.age = 32
@method_friendly_decorator
def sayYourAge(self, lie):
print("I am {0}, what did you think?".format(self.age + lie))
l = Lucy()
l.sayYourAge(-3)
#outputs: I am 26, what did you think?
```

If you‚Äôre making general-purpose decorator--one you‚Äôll apply to any function or method, no matter its arguments--then just use `*args, **kwargs`

:

```
def a_decorator_passing_arbitrary_arguments(function_to_decorate):
# The wrapper accepts any arguments
def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs):
print("Do I have args?:")
print(args)
print(kwargs)
# Then you unpack the arguments, here *args, **kwargs
# If you are not familiar with unpacking, check:
# http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
function_to_decorate(*args, **kwargs)
return a_wrapper_accepting_arbitrary_arguments
@a_decorator_passing_arbitrary_arguments
def function_with_no_argument():
print("Python is cool, no argument here.")
function_with_no_argument()
#outputs
#Do I have args?:
#()
#{}
#Python is cool, no argument here.
@a_decorator_passing_arbitrary_arguments
def function_with_arguments(a, b, c):
print(a, b, c)
function_with_arguments(1,2,3)
#outputs
#Do I have args?:
#(1, 2, 3)
#{}
#1 2 3
@a_decorator_passing_arbitrary_arguments
def function_with_named_arguments(a, b, c, platypus="Why not ?"):
print("Do {0}, {1} and {2} like platypus? {3}".format(a, b, c, platypus))
function_with_named_arguments("Bill", "Linus", "Steve", platypus="Indeed!")
#outputs
#Do I have args ? :
#("Bill", "Linus", "Steve")
#{"platypus": "Indeed!"}
#Do Bill, Linus and Steve like platypus? Indeed!
class Mary(object):
def __init__(self):
self.age = 31
@a_decorator_passing_arbitrary_arguments
def sayYourAge(self, lie=-3): # You can now add a default value
print("I am {0}, what did you think?".format(self.age + lie))
m = Mary()
m.sayYourAge()
#outputs
# Do I have args?:
#(<__main__.Mary object at 0xb7d303ac>,)
#{}
#I am 28, what did you think?
```

Great, now what would you say about passing arguments to the decorator itself?

This can get somewhat twisted, since a decorator must accept a function as an argument. Therefore, you cannot pass the decorated function‚Äôs arguments directly to the decorator.

Before rushing to the solution, let‚Äôs write a little reminder:

```
# Decorators are ORDINARY functions
def my_decorator(func):
print("I am an ordinary function")
def wrapper():
print("I am function returned by the decorator")
func()
return wrapper
# Therefore, you can call it without any "@"
def lazy_function():
print("zzzzzzzz")
decorated_function = my_decorator(lazy_function)
#outputs: I am an ordinary function
# It outputs "I am an ordinary function", because that‚Äôs just what you do:
# calling a function. Nothing magic.
@my_decorator
def lazy_function():
print("zzzzzzzz")
#outputs: I am an ordinary function
```

It‚Äôs exactly the same. "`my_decorator`

" is called. So when you `@my_decorator`

, you are telling Python to call the function "labelled by the variable "`my_decorator`

"".

This is important! The label you give can point directly to the decorator‚Äî**or not**.

Let‚Äôs get evil. ‚ò∫

```
def decorator_maker():
print("I make decorators! I am executed only once: "
"when you make me create a decorator.")
def my_decorator(func):
print("I am a decorator! I am executed only when you decorate a function.")
def wrapped():
print("I am the wrapper around the decorated function. "
"I am called when you call the decorated function. "
"As the wrapper, I return the RESULT of the decorated function.")
return func()
print("As the decorator, I return the wrapped function.")
return wrapped
print("As a decorator maker, I return a decorator")
return my_decorator
# Let‚Äôs create a decorator. It‚Äôs just a new function after all.
new_decorator = decorator_maker()
#outputs:
#I make decorators! I am executed only once: when you make me create a decorator.
#As a decorator maker, I return a decorator
# Then we decorate the function
def decorated_function():
print("I am the decorated function.")
decorated_function = new_decorator(decorated_function)
#outputs:
#I am a decorator! I am executed only when you decorate a function.
#As the decorator, I return the wrapped function
# Let‚Äôs call the function:
decorated_function()
#outputs:
#I am the wrapper around the decorated function. I am called when you call the decorated function.
#As the wrapper, I return the RESULT of the decorated function.
#I am the decorated function.
```

No surprise here.

Let‚Äôs do EXACTLY the same thing, but skip all the pesky intermediate variables:

```
def decorated_function():
print("I am the decorated function.")
decorated_function = decorator_maker()(decorated_function)
#outputs:
#I make decorators! I am executed only once: when you make me create a decorator.
#As a decorator maker, I return a decorator
#I am a decorator! I am executed only when you decorate a function.
#As the decorator, I return the wrapped function.
# Finally:
decorated_function()
#outputs:
#I am the wrapper around the decorated function. I am called when you call the decorated function.
#As the wrapper, I return the RESULT of the decorated function.
#I am the decorated function.
```

Let‚Äôs make it *even shorter*:

```
@decorator_maker()
def decorated_function():
print("I am the decorated function.")
#outputs:
#I make decorators! I am executed only once: when you make me create a decorator.
#As a decorator maker, I return a decorator
#I am a decorator! I am executed only when you decorate a function.
#As the decorator, I return the wrapped function.
#Eventually:
decorated_function()
#outputs:
#I am the wrapper around the decorated function. I am called when you call the decorated function.
#As the wrapper, I return the RESULT of the decorated function.
#I am the decorated function.
```

Hey, did you see that? We used a function call with the "`@`

" syntax! :-)

So, back to decorators with arguments. If we can use functions to generate the decorator on the fly, we can pass arguments to that function, right?

```
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
print("I make decorators! And I accept arguments: {0}, {1}".format(decorator_arg1, decorator_arg2))
def my_decorator(func):
# The ability to pass arguments here is a gift from closures.
# If you are not comfortable with closures, you can assume it‚Äôs ok,
# or read: https://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python
print("I am the decorator. Somehow you passed me arguments: {0}, {1}".format(decorator_arg1, decorator_arg2))
# Don"t confuse decorator arguments and function arguments!
def wrapped(function_arg1, function_arg2) :
print("I am the wrapper around the decorated function.
"
"I can access all the variables
"
" - from the decorator: {0} {1}
"
" - from the function call: {2} {3}
"
"Then I can pass them to the decorated function"
.format(decorator_arg1, decorator_arg2,
function_arg1, function_arg2))
return func(function_arg1, function_arg2)
return wrapped
return my_decorator
@decorator_maker_with_arguments("Leonard", "Sheldon")
def decorated_function_with_arguments(function_arg1, function_arg2):
print("I am the decorated function and only knows about my arguments: {0}"
" {1}".format(function_arg1, function_arg2))
decorated_function_with_arguments("Rajesh", "Howard")
#outputs:
#I make decorators! And I accept arguments: Leonard Sheldon
#I am the decorator. Somehow you passed me arguments: Leonard Sheldon
#I am the wrapper around the decorated function.
#I can access all the variables
# - from the decorator: Leonard Sheldon
# - from the function call: Rajesh Howard
#Then I can pass them to the decorated function
#I am the decorated function and only knows about my arguments: Rajesh Howard
```

Here it is: a decorator with arguments. Arguments can be set as variable:

```
c1 = "Penny"
c2 = "Leslie"
@decorator_maker_with_arguments("Leonard", c1)
def decorated_function_with_arguments(function_arg1, function_arg2):
print("I am the decorated function and only knows about my arguments:"
" {0} {1}".format(function_arg1, function_arg2))
decorated_function_with_arguments(c2, "Howard")
#outputs:
#I make decorators! And I accept arguments: Leonard Penny
#I am the decorator. Somehow you passed me arguments: Leonard Penny
#I am the wrapper around the decorated function.
#I can access all the variables
# - from the decorator: Leonard Penny
# - from the function call: Leslie Howard
#Then I can pass them to the decorated function
#I am the decorated function and only know about my arguments: Leslie Howard
```

As you can see, you can pass arguments to the decorator like any function using this trick. You can even use `*args, **kwargs`

if you wish. But remember decorators are called **only once**. Just when Python imports the script. You can"t dynamically set the arguments afterwards. When you do "import x", **the function is already decorated**, so you can"t
change anything.

Okay, as a bonus, I"ll give you a snippet to make any decorator accept generically any argument. After all, in order to accept arguments, we created our decorator using another function.

We wrapped the decorator.

Anything else we saw recently that wrapped function?

Oh yes, decorators!

Let‚Äôs have some fun and write a decorator for the decorators:

```
def decorator_with_args(decorator_to_enhance):
"""
This function is supposed to be used as a decorator.
It must decorate an other function, that is intended to be used as a decorator.
Take a cup of coffee.
It will allow any decorator to accept an arbitrary number of arguments,
saving you the headache to remember how to do that every time.
"""
# We use the same trick we did to pass arguments
def decorator_maker(*args, **kwargs):
# We create on the fly a decorator that accepts only a function
# but keeps the passed arguments from the maker.
def decorator_wrapper(func):
# We return the result of the original decorator, which, after all,
# IS JUST AN ORDINARY FUNCTION (which returns a function).
# Only pitfall: the decorator must have this specific signature or it won"t work:
return decorator_to_enhance(func, *args, **kwargs)
return decorator_wrapper
return decorator_maker
```

It can be used as follows:

```
# You create the function you will use as a decorator. And stick a decorator on it :-)
# Don"t forget, the signature is "decorator(func, *args, **kwargs)"
@decorator_with_args
def decorated_decorator(func, *args, **kwargs):
def wrapper(function_arg1, function_arg2):
print("Decorated with {0} {1}".format(args, kwargs))
return func(function_arg1, function_arg2)
return wrapper
# Then you decorate the functions you wish with your brand new decorated decorator.
@decorated_decorator(42, 404, 1024)
def decorated_function(function_arg1, function_arg2):
print("Hello {0} {1}".format(function_arg1, function_arg2))
decorated_function("Universe and", "everything")
#outputs:
#Decorated with (42, 404, 1024) {}
#Hello Universe and everything
# Whoooot!
```

I know, the last time you had this feeling, it was after listening a guy saying: "before understanding recursion, you must first understand recursion". But now, don"t you feel good about mastering this?

- Decorators were introduced in Python 2.4, so be sure your code will be run on >= 2.4.
- Decorators slow down the function call. Keep that in mind.
**You cannot un-decorate a function.**(There*are*hacks to create decorators that can be removed, but nobody uses them.) So once a function is decorated, it‚Äôs decorated*for all the code*.- Decorators wrap functions, which can make them hard to debug. (This gets better from Python >= 2.5; see below.)

The `functools`

module was introduced in Python 2.5. It includes the function `functools.wraps()`

, which copies the name, module, and docstring of the decorated function to its wrapper.

(Fun fact: `functools.wraps()`

is a decorator! ‚ò∫)

```
# For debugging, the stacktrace prints you the function __name__
def foo():
print("foo")
print(foo.__name__)
#outputs: foo
# With a decorator, it gets messy
def bar(func):
def wrapper():
print("bar")
return func()
return wrapper
@bar
def foo():
print("foo")
print(foo.__name__)
#outputs: wrapper
# "functools" can help for that
import functools
def bar(func):
# We say that "wrapper", is wrapping "func"
# and the magic begins
@functools.wraps(func)
def wrapper():
print("bar")
return func()
return wrapper
@bar
def foo():
print("foo")
print(foo.__name__)
#outputs: foo
```

**Now the big question:** What can I use decorators for?

Seem cool and powerful, but a practical example would be great. Well, there are 1000 possibilities. Classic uses are extending a function behavior from an external lib (you can"t modify it), or for debugging (you don"t want to modify it because it‚Äôs temporary).

You can use them to extend several functions in a DRY‚Äôs way, like so:

```
def benchmark(func):
"""
A decorator that prints the time a function takes
to execute.
"""
import time
def wrapper(*args, **kwargs):
t = time.clock()
res = func(*args, **kwargs)
print("{0} {1}".format(func.__name__, time.clock()-t))
return res
return wrapper
def logging(func):
"""
A decorator that logs the activity of the script.
(it actually just prints it, but it could be logging!)
"""
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
print("{0} {1} {2}".format(func.__name__, args, kwargs))
return res
return wrapper
def counter(func):
"""
A decorator that counts and prints the number of times a function has been executed
"""
def wrapper(*args, **kwargs):
wrapper.count = wrapper.count + 1
res = func(*args, **kwargs)
print("{0} has been used: {1}x".format(func.__name__, wrapper.count))
return res
wrapper.count = 0
return wrapper
@counter
@benchmark
@logging
def reverse_string(string):
return str(reversed(string))
print(reverse_string("Able was I ere I saw Elba"))
print(reverse_string("A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama!"))
#outputs:
#reverse_string ("Able was I ere I saw Elba",) {}
#wrapper 0.0
#wrapper has been used: 1x
#ablE was I ere I saw elbA
#reverse_string ("A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama!",) {}
#wrapper 0.0
#wrapper has been used: 2x
#!amanaP :lanac a ,noep a ,stah eros ,raj a ,hsac ,oloR a ,tur a ,mapS ,snip ,eperc a ,)lemac a ro( niaga gab ananab a ,gat a ,nat a ,gab ananab a ,gag a ,inoracam ,elacrep ,epins ,spam ,arutaroloc a ,shajar ,soreh ,atsap ,eonac a ,nalp a ,nam A
```

Of course the good thing with decorators is that you can use them right away on almost anything without rewriting. DRY, I said:

```
@counter
@benchmark
@logging
def get_random_futurama_quote():
from urllib import urlopen
result = urlopen("http://subfusion.net/cgi-bin/quote.pl?quote=futurama").read()
try:
value = result.split("<br><b><hr><br>")[1].split("<br><br><hr>")[0]
return value.strip()
except:
return "No, I"m ... doesn"t!"
print(get_random_futurama_quote())
print(get_random_futurama_quote())
#outputs:
#get_random_futurama_quote () {}
#wrapper 0.02
#wrapper has been used: 1x
#The laws of science be a harsh mistress.
#get_random_futurama_quote () {}
#wrapper 0.01
#wrapper has been used: 2x
#Curse you, merciful Poseidon!
```

Python itself provides several decorators: `property`

, `staticmethod`

, etc.

- Django uses decorators to manage caching and view permissions.
- Twisted to fake inlining asynchronous functions calls.

This really is a large playground.

Specify the keyword args `linestyle`

and/or `marker`

in your call to `plot`

.

For example, using a dashed line and blue circle markers:

```
plt.plot(range(10), linestyle="--", marker="o", color="b")
```

A shortcut call for the same thing:

```
plt.plot(range(10), "--bo")
```

Here is a list of the possible line and marker styles:

```
================ ===============================
character description
================ ===============================
- solid line style
-- dashed line style
-. dash-dot line style
: dotted line style
. point marker
, pixel marker
o circle marker
v triangle_down marker
^ triangle_up marker
< triangle_left marker
> triangle_right marker
1 tri_down marker
2 tri_up marker
3 tri_left marker
4 tri_right marker
s square marker
p pentagon marker
* star marker
h hexagon1 marker
H hexagon2 marker
+ plus marker
x x marker
D diamond marker
d thin_diamond marker
| vline marker
_ hline marker
================ ===============================
```

*edit:* with an example of marking an arbitrary subset of points, as requested in the comments:

```
import numpy as np
import matplotlib.pyplot as plt
xs = np.linspace(-np.pi, np.pi, 30)
ys = np.sin(xs)
markers_on = [12, 17, 18, 19]
plt.plot(xs, ys, "-gD", markevery=markers_on)
plt.show()
```

This last example using the `markevery`

kwarg is possible in since 1.4+, due to the merge of this feature branch. If you are stuck on an older version of matplotlib, you can still achieve the result by overlaying a scatterplot on the line plot. See the edit history for more details.

First find the difference between the start point and the end point (here, this is more of a directed line segment, not a "line", since lines extend infinitely and don"t start at a particular point).

```
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
```

Then calculate the angle (which runs from the positive X axis at `P1`

to the positive Y axis at `P1`

).

```
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
```

But `arctan`

may not be ideal, because dividing the differences this way will erase the distinction needed to distinguish which quadrant the angle is in (see below). Use the following instead if your language includes an `atan2`

function:

```
angleInDegrees = atan2(deltaY, deltaX) * 180 / PI
```

EDIT (Feb. 22, 2017): In general, however, calling `atan2(deltaY,deltaX)`

just to get the proper angle for `cos`

and `sin`

may be inelegant. In those cases, you can often do the following instead:

- Treat
`(deltaX, deltaY)`

as a vector. - Normalize that vector to a unit vector. To do so, divide
`deltaX`

and`deltaY`

by the vector"s length (`sqrt(deltaX*deltaX+deltaY*deltaY)`

), unless the length is 0. - After that,
`deltaX`

will now be the cosine of the angle between the vector and the horizontal axis (in the direction from the positive X to the positive Y axis at`P1`

). - And
`deltaY`

will now be the sine of that angle. - If the vector"s length is 0, it won"t have an angle between it and the horizontal axis (so it won"t have a meaningful sine and cosine).

EDIT (Feb. 28, 2017): Even without normalizing `(deltaX, deltaY)`

:

- The sign of
`deltaX`

will tell you whether the cosine described in step 3 is positive or negative. - The sign of
`deltaY`

will tell you whether the sine described in step 4 is positive or negative. - The signs of
`deltaX`

and`deltaY`

will tell you which quadrant the angle is in, in relation to the positive X axis at`P1`

:`+deltaX`

,`+deltaY`

: 0 to 90 degrees.`-deltaX`

,`+deltaY`

: 90 to 180 degrees.`-deltaX`

,`-deltaY`

: 180 to 270 degrees (-180 to -90 degrees).`+deltaX`

,`-deltaY`

: 270 to 360 degrees (-90 to 0 degrees).

**An implementation in Python using radians (provided on July 19, 2015 by Eric Leschinski, who edited my answer):**

```
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
```

All tests pass. See https://en.wikipedia.org/wiki/Unit_circle

Here"s a Python version:

```
from math import radians, cos, sin, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance in kilometers between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371 # Radius of earth in kilometers. Use 3956 for miles. Determines return value units.
return c * r
```

The rate at which we produce data is growing steadily, thus creating even larger streams of continuously evolving data. Online news, micro-blogs, search queries are just a few examples of these contin...

10/07/2020

Computer languages have so far been of the ‘interpreted’ or the ‘compiled’ type. Compiled languages (like ‘C’) have been more common. You prepare a program, save it (the debugged version),...

23/09/2020

Learning to code is tremendous fun as you can get instant results, no matter how much more you have to learn. In fact, it’s such fun creating games and programs that it feels effortless once you’r...

23/09/2020

We are experiencing a renaissance of artificial intelligence, and everyone and their neighbor wants to be a part of this movement. That’s quite likely why you are browsing through this book. There a...

23/09/2020

X
# Submit new EBook