aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/api.py2
-rw-r--r--bot/constants.py1
-rw-r--r--bot/resources/tags/defaultdict.md21
-rw-r--r--bot/resources/tags/dictcomps.md24
-rw-r--r--bot/resources/tags/f-strings.md20
-rw-r--r--bot/resources/tags/listcomps.md23
-rw-r--r--bot/resources/tags/local-file.md23
-rw-r--r--config-default.yml3
8 files changed, 77 insertions, 40 deletions
diff --git a/bot/api.py b/bot/api.py
index d93f9f2ba..6ce9481f4 100644
--- a/bot/api.py
+++ b/bot/api.py
@@ -53,7 +53,7 @@ class APIClient:
@staticmethod
def _url_for(endpoint: str) -> str:
- return f"{URLs.site_schema}{URLs.site_api}/{quote_url(endpoint)}"
+ return f"{URLs.site_api_schema}{URLs.site_api}/{quote_url(endpoint)}"
async def close(self) -> None:
"""Close the aiohttp session."""
diff --git a/bot/constants.py b/bot/constants.py
index 95e22513f..91e41e334 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -530,6 +530,7 @@ class URLs(metaclass=YAMLGetter):
site: str
site_api: str
site_schema: str
+ site_api_schema: str
# Site endpoints
site_logs_view: str
diff --git a/bot/resources/tags/defaultdict.md b/bot/resources/tags/defaultdict.md
new file mode 100644
index 000000000..b6c3175fc
--- /dev/null
+++ b/bot/resources/tags/defaultdict.md
@@ -0,0 +1,21 @@
+**[`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict)**
+
+The Python `defaultdict` type behaves almost exactly like a regular Python dictionary, but if you try to access or modify a missing key, the `defaultdict` will automatically insert the key and generate a default value for it.
+While instantiating a `defaultdict`, we pass in a function that tells it how to create a default value for missing keys.
+
+```py
+>>> from collections import defaultdict
+>>> my_dict = defaultdict(int)
+>>> my_dict
+defaultdict(<class 'int'>, {})
+```
+
+In this example, we've used the `int` class which returns 0 when called like a function, so any missing key will get a default value of 0. You can also get an empty list by default with `list` or an empty string with `str`.
+
+```py
+>>> my_dict["foo"]
+0
+>>> my_dict["bar"] += 5
+>>> my_dict
+defaultdict(<class 'int'>, {'foo': 0, 'bar': 5})
+```
diff --git a/bot/resources/tags/dictcomps.md b/bot/resources/tags/dictcomps.md
index 11867d77b..6c8018761 100644
--- a/bot/resources/tags/dictcomps.md
+++ b/bot/resources/tags/dictcomps.md
@@ -1,20 +1,14 @@
-**Dictionary Comprehensions**
-
-Like lists, there is a convenient way of creating dictionaries:
+Dictionary comprehensions (*dict comps*) provide a convenient way to make dictionaries, just like list comps:
```py
->>> ftoc = {f: round((5/9)*(f-32)) for f in range(-40,101,20)}
->>> print(ftoc)
-{-40: -40, -20: -29, 0: -18, 20: -7, 40: 4, 60: 16, 80: 27, 100: 38}
+>>> {word.lower(): len(word) for word in ('I', 'love', 'Python')}
+{'i': 1, 'love': 4, 'python': 6}
```
-In the example above, I created a dictionary of temperatures in Fahrenheit, that are mapped to (*roughly*) their Celsius counterpart within a small range. These comprehensions are useful for succinctly creating dictionaries from some other sequence.
+The syntax is very similar to list comps except that you surround it with curly braces and have two expressions: one for the key and one for the value.
-They are also very useful for inverting the key value pairs of a dictionary that already exists, such that the value in the old dictionary is now the key, and the corresponding key is now its value:
+One can use a dict comp to change an existing dictionary using its `items` method
```py
->>> ctof = {v:k for k, v in ftoc.items()}
->>> print(ctof)
-{-40: -40, -29: -20, -18: 0, -7: 20, 4: 40, 16: 60, 27: 80, 38: 100}
+>>> first_dict = {'i': 1, 'love': 4, 'python': 6}
+>>> {key.upper(): value * 2 for key, value in first_dict.items()}
+{'I': 2, 'LOVE': 8, 'PYTHON': 12}
```
-
-Also like list comprehensions, you can add a conditional to it in order to filter out items you don't want.
-
-For more information and examples, check [PEP 274](https://www.python.org/dev/peps/pep-0274/)
+For more information and examples, check out [PEP 274](https://www.python.org/dev/peps/pep-0274/)
diff --git a/bot/resources/tags/f-strings.md b/bot/resources/tags/f-strings.md
index 69bc82487..5ccafe723 100644
--- a/bot/resources/tags/f-strings.md
+++ b/bot/resources/tags/f-strings.md
@@ -1,17 +1,9 @@
-In Python, there are several ways to do string interpolation, including using `%s`\'s and by using the `+` operator to concatenate strings together. However, because some of these methods offer poor readability and require typecasting to prevent errors, you should for the most part be using a feature called format strings.
+Creating a Python string with your variables using the `+` operator can be difficult to write and read. F-strings (*format-strings*) make it easy to insert values into a string. If you put an `f` in front of the first quote, you can then put Python expressions between curly braces in the string.
-**In Python 3.6 or later, we can use f-strings like this:**
```py
-snake = "Pythons"
-print(f"{snake} are some of the largest snakes in the world")
-```
-**In earlier versions of Python or in projects where backwards compatibility is very important, use str.format() like this:**
-```py
-snake = "Pythons"
-
-# With str.format() you can either use indexes
-print("{0} are some of the largest snakes in the world".format(snake))
-
-# Or keyword arguments
-print("{family} are some of the largest snakes in the world".format(family=snake))
+>>> snake = "pythons"
+>>> number = 21
+>>> f"There are {number * 2} {snake} on the plane."
+"There are 42 pythons on the plane."
```
+Note that even when you include an expression that isn't a string, like `number * 2`, Python will convert it to a string for you.
diff --git a/bot/resources/tags/listcomps.md b/bot/resources/tags/listcomps.md
index 0003b9bb8..ba00a4bf7 100644
--- a/bot/resources/tags/listcomps.md
+++ b/bot/resources/tags/listcomps.md
@@ -1,14 +1,19 @@
-Do you ever find yourself writing something like:
+Do you ever find yourself writing something like this?
```py
-even_numbers = []
-for n in range(20):
- if n % 2 == 0:
- even_numbers.append(n)
+>>> squares = []
+>>> for n in range(5):
+... squares.append(n ** 2)
+[0, 1, 4, 9, 16]
```
-Using list comprehensions can simplify this significantly, and greatly improve code readability. If we rewrite the example above to use list comprehensions, it would look like this:
+Using list comprehensions can make this both shorter and more readable. As a list comprehension, the same code would look like this:
```py
-even_numbers = [n for n in range(20) if n % 2 == 0]
+>>> [n ** 2 for n in range(5)]
+[0, 1, 4, 9, 16]
+```
+List comprehensions also get an `if` statement:
+```python
+>>> [n ** 2 for n in range(5) if n % 2 == 0]
+[0, 4, 16]
```
-This also works for generators, dicts and sets by using `()` or `{}` instead of `[]`.
-For more info, see [this pythonforbeginners.com post](http://www.pythonforbeginners.com/basics/list-comprehensions-in-python) or [PEP 202](https://www.python.org/dev/peps/pep-0202/).
+For more info, see [this pythonforbeginners.com post](http://www.pythonforbeginners.com/basics/list-comprehensions-in-python).
diff --git a/bot/resources/tags/local-file.md b/bot/resources/tags/local-file.md
new file mode 100644
index 000000000..ae41d589c
--- /dev/null
+++ b/bot/resources/tags/local-file.md
@@ -0,0 +1,23 @@
+Thanks to discord.py, sending local files as embed images is simple. You have to create an instance of [`discord.File`](https://discordpy.readthedocs.io/en/latest/api.html#discord.File) class:
+```py
+# When you know the file exact path, you can pass it.
+file = discord.File("/this/is/path/to/my/file.png", filename="file.png")
+
+# When you have the file-like object, then you can pass this instead path.
+with open("/this/is/path/to/my/file.png", "rb") as f:
+ file = discord.File(f)
+```
+When using the file-like object, you have to open it in `rb` mode. Also, in this case, passing `filename` to it is not necessary.
+Please note that `filename` can't contain underscores. This is a Discord limitation.
+
+[`discord.Embed`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed) instances have a [`set_image`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed.set_image) method which can be used to set an attachment as an image:
+```py
+embed = discord.Embed()
+# Set other fields
+embed.set_image(url="attachment://file.png") # Filename here must be exactly same as attachment filename.
+```
+After this, you can send an embed with an attachment to Discord:
+```py
+await channel.send(file=file, embed=embed)
+```
+This example uses [`discord.TextChannel`](https://discordpy.readthedocs.io/en/latest/api.html#discord.TextChannel) for sending, but any instance of [`discord.abc.Messageable`](https://discordpy.readthedocs.io/en/latest/api.html#discord.abc.Messageable) can be used for sending.
diff --git a/config-default.yml b/config-default.yml
index d3b267159..d7415c821 100644
--- a/config-default.yml
+++ b/config-default.yml
@@ -335,7 +335,8 @@ keys:
urls:
# PyDis site vars
site: &DOMAIN "pythondiscord.com"
- site_api: &API !JOIN ["api.", *DOMAIN]
+ site_api: &API "pydis-api.default.svc.cluster.local"
+ site_api_schema: "http://"
site_paste: &PASTE !JOIN ["paste.", *DOMAIN]
site_schema: &SCHEMA "https://"
site_staff: &STAFF !JOIN ["staff.", *DOMAIN]