Skip to content

Commit da5b5f7

Browse files
authored
Merge pull request ContainerSolutions#83 from ContainerSolutions/im/content-2020-07-16
Im/content 2020 07 16
2 parents 4b9975b + 2fac3a0 commit da5b5f7

File tree

5 files changed

+222
-46
lines changed

5 files changed

+222
-46
lines changed

content/posts/python/module-has-no-attribute.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ summary: "Recieving an AttributeError telling you that your module doesn't have
66
## Overview {#overview}
77

88
```
9-
python main.py
9+
python main.py
1010
Traceback (most recent call last):
1111
File "main.py", line 2, in <module>
1212
foo.bar()

content/posts/python/name-is-not-defined.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ summary: "When calling a method on a module's class you get a NameError telling
55

66
## Overview {#overview}
77

8+
9+
This issue happens when you try to invoke a class within a module without specifying the module anywhere
10+
11+
## Check RunBook Match {#check-runbook-match}
12+
13+
If you see an error like this:
14+
815
```
916
Traceback (most recent call last):
1017
File "main.py", line 2, in <module>
1118
Foo.hello()
1219
NameError: name 'Foo' is not defined
1320
```
1421

15-
This issue happens when you try to invoke a class within a module without specifying the module anywhere
16-
17-
## Check RunBook Match {#check-runbook-match}
22+
then this runbook is a match.
1823

1924
When you call a class method within a from a module you expect to see the result of that call and for that class to be defined.
2025

content/posts/python/object-is-not-subscriptable.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@ summary: "Fixing this cryptic Python TypeError"
55

66
## Overview {#overview}
77

8-
You get an error complaining:
9-
`TypeError: object is not subscriptable`
8+
This problem is caused by trying to access an object that cannot be indexed as though it can be accessed via an index.
109

11-
Specific examples:
12-
* `TypeError: 'type' object is not subscriptable`
13-
* `TypeError: 'function' object is not subscriptable`
14-
15-
e.g.
10+
For example, given the following error:
1611

1712
```python
1813
Traceback (most recent call last):
@@ -21,9 +16,19 @@ Traceback (most recent call last):
2116
TypeError: 'type' object is not subscriptable
2217
```
2318

24-
## Problem {#problem}
19+
The code is trying to access `map[value]` but `map` is already a built-in type that doesn't support accessing indexes.
20+
21+
You would get a similar error if you tried to call `print[42]`, because `print` is a built-in function.
22+
23+
## Check RunBook Match {#check-runbook-match}
2524

26-
This problem is caused when you treat an object that cannot be indexed by trying to access it by an index or "subscript". In the above example, I'm looking for `map[value]` but `map` is already a built-in type that doesn't support accessing indexes. You would get a similar error if you tried to call `print[42]` because `print` is a built-in function.
25+
If you get an error complaining:
26+
27+
`TypeError: object is not subscriptable`
28+
29+
Specific examples:
30+
* `TypeError: 'type' object is not subscriptable`
31+
* `TypeError: 'function' object is not subscriptable`
2732

2833
## Initial Steps Overview {#initial-steps-overview}
2934

@@ -52,7 +57,7 @@ import builtins
5257
dir(builtins)
5358

5459
# For Python 2.0
55-
import __builtin__
60+
import __builtin__
5661
dir(__builtin__)
5762
```
5863

@@ -146,7 +151,7 @@ But don't just take our word for it: [see here](https://stackoverflow.com/q/9109
146151

147152
## Authors {#authors}
148153

149-
[@Gerry](https://github.com/gerrywastaken)
154+
[@Gerry](https://github.com/gerrywastaken)
150155

151156
[//]: # (REFERENCED DOCS)
152157
[//]: # (https://docs.python.org/2.0/ref/subscriptions.html DONE)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: "Ordinal Not in Range"
3+
summary: "Python encoding/decoding errors"
4+
draft: true
5+
---
6+
7+
## Overview {#overview}
8+
9+
This issue happens when Python can't correctly work with a string variable.
10+
11+
Strings can contain any sequence of bytes, but when Python is asked to work with the string, it may decide that the string contains invalid bytes.
12+
13+
In these situations, an error is often thrown.
14+
15+
## Check RunBook Match {#check-runbook-match}
16+
17+
If you see an error that looks like this:
18+
19+
```
20+
Traceback (most recent call last):
21+
File "unicode_ex.py", line 3, in
22+
print str(a) # this throws an exception
23+
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa1' in position 0: ordinal not in range(128)
24+
```
25+
26+
ie one that mentions `ordinal not in range` and/or `codec can't encode character` or `codec can't decode character` then this runbooks is a match.
27+
28+
## Initial Steps Overview {#initial-steps-overview}
29+
30+
1) [Check Python version](#step-1)
31+
32+
2) [Check ](#step-2)
33+
34+
## Detailed Steps {#detailed-steps}
35+
36+
### 1) Check Python version {#step-1}
37+
38+
The Python version you are using is significant.
39+
40+
### 2) TODO {#step-2}
41+
42+
[Link to Solution A](#solution-a)
43+
44+
## Solutions List {#solutions-list}
45+
46+
A) [Solution](#solution-a)
47+
48+
## Solutions Detail {#solutions-detail}
49+
50+
### Solution A {#solution-a}
51+
52+
## Check Resolution {#check-resolution}
53+
54+
## Further Steps {#further-steps}
55+
56+
1) [Further Step 1](#further-steps-1)
57+
58+
### Further Step 1 {#further-steps-1}
59+
60+
## Further Information {#further-information}
61+
62+
## Owner {#owner}
63+
64+
email
65+
66+
[//]: # (REFERENCED DOCS)
67+
[//]: # (http://effbot.org/pyfaq/what-does-unicodeerror-ascii-decoding-encoding-error-ordinal-not-in-range-128-mean.htm - TODO)
68+
[//]: # (https://markhneedham.com/blog/2015/05/21/python-unicodeencodeerror-ascii-codec-cant-encode-character-uxfc-in-position-11-ordinal-not-in-range128/ - TODO)
69+
[//]: # (https://pythonhosted.org/kitchen/unicode-frustrations.html - TODO)
70+
[//]: # (https://stackoverflow.com/questions/9942594/unicodeencodeerror-ascii-codec-cant-encode-character-u-xa0-in-position-20 - TODO)
71+
[//]: # (https://www.b-list.org/weblog/2007/nov/10/unicode/ - TODO)
72+
[//]: # (https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ - TODO)
73+
[//]: # (https://www.saltycrane.com/blog/2008/11/python-unicodeencodeerror-ascii-codec-cant-encode-character/ - TODO)
74+
Lines changed: 123 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,159 @@
11
---
22
title: "Wrong Number of Arguments"
3-
summary: "Summary here"
3+
summary: "'F() takes X positional arguments but Y were given' errors"
44
---
55

66
## Overview {#overview}
77

8+
Python can report that you are passing one more argument than it appears you are sending.
9+
10+
For example, you are passing two arguments, but Python claims you have passed three.
11+
12+
## Check RunBook Match {#check-runbook-match}
13+
14+
If you see an error that looks like this:
15+
816
```
917
Traceback (most recent call last):
1018
File "afile.py", line 15, in <module>
1119
print(aFunction(width, height))
1220
TypeError: aFunction() takes 2 positional arguments but 3 were given
1321
```
1422

15-
But you're only passing two arguments. Python is implicitly passing the object instance.
23+
Then this runbook is a match.
1624

17-
## Check RunBook Match {#check-runbook-match}
25+
## Initial Steps Overview {#initial-steps-overview}
26+
27+
1) [Method in Python class?](#step-1)
1828

19-
When Python says that you are passing one more argument than you are actually sending. eg. You are passing two arguments but Python claims you have passed 3.
29+
2) [Method outside Python class?](#step-2)
30+
31+
## Detailed Steps {#detailed-steps}
2032

21-
This may be because you have set a method to be @classmethod when you meant to use @staticmethod and so the class is automatically passed as the first argument.
33+
### 1) Method inside Python class? {#step-1}
2234

23-
A similar situation is true for instance methods where the instance is automatically passed as the first argument.
35+
This issue occurs because your method is declared in the context of a Python class.
2436

25-
Here's a quick look at situations where arguments are implicitly being passed. Note that in all three we only pass two variables, but in the case of the instance and class methods, Python adds an argument of it's own which needs to be there in the method's definition.
37+
For example, if your method is `bar` it is indented inside a `class` block, like so:
2638

2739
```python
2840
class Foo():
2941
def bar(self, a, b):
3042
print("bar:", self, a, b)
43+
```
3144

32-
@classmethod
33-
def tee(cls, a, b):
34-
print("tee:", cls, a, b)
45+
If your method is outside a Python `class`, then go to [step 2](#step-2).
3546

36-
@staticmethod
37-
def qux(a, b):
38-
print("qux:", a, b)
47+
If your method is inside a Python `class`, then there are a number of options to consider.
3948

40-
Foo().bar(1, 2)
41-
Foo.tee(1, 2)
42-
Foo.qux(1, 2)
49+
#### 1.1) Instance method {#step-1-1}
4350

44-
# Output
51+
If your method is a straighforward instance method (ie has no decorators such as `@staticmethod` or `@classmethod` above the declaration), then it is likely that you forgot to add a first argument to the method signature.
52+
53+
See [solution A](#solution-a) if this is the case.
54+
55+
#### 1.2) Class method {#step-1-2}
56+
If your method is a class method (ie has the `@classmethod` decorator above the declaration), then it is likely that you forgot to add a first argument to the method signature.
57+
58+
See [solution B](#solution-b) if this is the case.
59+
60+
#### 1.3) Static method {#step-1-2}
61+
62+
It is also possible that your method should be a static method.
63+
64+
If your method is a utility function that:
65+
66+
- doesn't need an instance of the class to be created to be used, or
67+
68+
- doesn't need to know about the class
69+
70+
then you may want to consider using a static method.
71+
72+
This resolves the problem through the method not receiving an unnecessary first argument (which both [1.1](#step-1-1) and [1.2](#step-1-2) above, do.
73+
74+
### 2) Method outside Python class? {#step-2}
75+
76+
If your method is outside a Python class, then it is likely that you have simply passed the wrong number of variables. Here's some tips that may help:
77+
78+
- Check that the function you believe you are calling is actually the function that is being called
79+
80+
- Look more closely at the function signature to determine what the correct number of arguments is and whether you are passing that number
4581

46-
# bar: <__main__.Foo object at 0x7fdc13acefa0> 1 2
47-
# tee: <class '__main__.Foo'> 1 2
48-
# qux: 1 2
49-
```
5082

5183
## Initial Steps Overview {#initial-steps-overview}
5284

53-
1) [Accept self for instance methods](#step-1)
54-
2) [Aceept class for Class methods](#step-2)
55-
3) [Switch to a Static method](#step-2)
85+
## Solutions List {#solutions-list}
5686

57-
## Detailed Steps {#detailed-steps}
87+
A) [Add `self` to method](#solution-a)
88+
89+
B) [Add `cls` argument to class method](#solution-b)
90+
91+
C) [Change method to `@staticmethod`](#solution-c)
92+
93+
94+
### A) Add `self` to method {#solution-a}
95+
Instance methods receive the instance as their first argument, so you must add this to the list of parameters for your method. By convention, this variable is normally named `self`. For example, change:
96+
97+
98+
```python
99+
[...]
100+
class Foo():
101+
def bar(a, b):
102+
print("bar:", self, a, b)
103+
```
104+
105+
to:
106+
107+
```python
108+
[...]
109+
class Foo():
110+
def bar(self, a, b):
111+
print("bar:", self, a, b)
112+
```
113+
114+
115+
### B) Add `cls` argument to method {#solution-b}
116+
Class methods receive a class, so you must add this to the list of parameters for your method. This is so that you can change values within the class or generate a new instance of the given class (factory method). By convention this variable is normally named `cls`. For example, change:
117+
118+
```python
119+
class Foo():
120+
[...]
121+
@classmethod
122+
def tee(a, b):
123+
print("tee:", cls, a, b)
124+
```
125+
126+
to:
127+
128+
```python
129+
class Foo():
130+
[...]
131+
@classmethod
132+
def tee(cls, a, b):
133+
print("tee:", cls, a, b)
134+
```
135+
136+
137+
### C) Change method to `@staticmethod` {#solution-c}
58138

59-
### 1) Accept self for instance methods {#step-1}
60-
Instance methods receive the instance as their first argument, so you must add this to the list of parameters for your method. By convention, this variable is normally named `self`.
139+
This is achieved by adding a decorator to the method, eg changing:
140+
141+
```python
142+
class Foo():
143+
[...]
144+
def qux(a, b):
145+
print("qux:", a, b)
146+
```
61147

62-
### 2) Aceept class for Class methods {#step-2}
63-
Class methods receive a class, so you must add this to the list of parameters for your method. This is so that you can change values within the class or generate a new instance of the given class (factory method). By convention this variable is normally named `cls`.
148+
to
64149

65-
### 3) Switch to a Static method {#step-2}
66-
If you method is just a utility function that doesn't need an instance or to know about the class, then you should probably be using a Static method. This way you will not receive an unnecessary first argument.
150+
```python
151+
class Foo():
152+
[...]
153+
@staticmethod
154+
def qux(a, b):
155+
print("qux:", a, b)
156+
```
67157

68158
## Check Resolution {#check-resolution}
69159

@@ -81,3 +171,5 @@ You should no longer receive the error about being given more positional argumen
81171

82172
[//]: # (REFERENCED DOCS)
83173
[//]: # (https://www.geeksforgeeks.org/class-method-vs-static-method-python/)
174+
[//]: # (https://realpython.com/primer-on-python-decorators/)
175+
[//]: # ()

0 commit comments

Comments
 (0)