PyBites Tips, Tricks & Quotes What's your favorite Python trick?


145

Since 3.5 the glob library supports recursive globs using “**” (note that in large directory trees this might be slow)
>>> import glob
>>> path = "/Users/bobbelderbos/code/bitesofpy/"
>>> glob.glob(path + "**/*py", recursive=True)

twitter icon more info
144

The string module makes it very easy to get letters, digits and more ...
>>> help(string)
...
...
DATA
    __all__ = ['ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'cap...
    ascii_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
    ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    digits = '0123456789'
    hexdigits = '0123456789abcdefABCDEF'
    octdigits = '01234567'
    printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU...
    punctuation = '!"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~'
    whitespace = ' \t\n\r\x0b\x0c'

twitter icon
143

Use itertools' chain.from_iterable to flatten a list of tuples (for more nesting take our Droste Bite: https://codechalleng.es/bites/84/)
>>> data = [(1, 'A', 'a'), (2, 'B', 'b'), (3, 'C', 'c')]
>>> list(itertools.chain(data))
[(1, 'A', 'a'), (2, 'B', 'b'), (3, 'C', 'c')]
>>> list(itertools.chain.from_iterable(data))
[1, 'A', 'a', 2, 'B', 'b', 3, 'C', 'c']

twitter icon more info
142

Need to check StackOverflow, but don’t want to leave the terminal? Use a neat tool called howdoi
$ cd code
$ mkdir howdoi && cd howdoi
$ python3.7 -m venv venv && source venv/bin/activate
(venv) $ pip install howdoi
$ vi .bashrc
...
$ alias howdoi
alias howdoi='cd $HOME/code/howdoi && source venv/bin/activate && howdoi'
$ howdoi zip enumerate
for index, (value1, value2) in enumerate(zip(data1, data2)):
    print index, value1 + value2

(venv) $ howdoi -a python Enum
★  Answer from https://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python ★
...
Animal.ant  # returns <Animal.ant: 1>
Animal['ant']  # returns <Animal.ant: 1> (string lookup)
Animal.ant.name  # returns 'ant' (inverse lookup)

or equivalently:
class Animal(Enum):
    ant = 1
    bee = 2
    cat = 3

...

twitter icon more info
141

Working with large numbers? Starting 3.6 you can make them more readable using an underscore / thousands separator.
>>> 10_000_000
10000000
>>> 10_000_000 is 10000000
True

twitter icon more info
140

strip can remove multiple leading and trailing characters at once, pretty convenient!
>>> pytest_summary = "=== 20 passed in 0.05 seconds ===\n"
>>> pytest_summary.strip("= \n")
'20 passed in 0.05 seconds'

# docs example
>>> 'www.example.com'.strip('cmowz.')
'example'
>>> comment_string = '#....... Section 3.2.1 Issue #32 .......'
>>> comment_string.strip('.#! ')
'Section 3.2.1 Issue #32'

twitter icon more info
139

Another standard library gem: operator.itemgetter lets you grab multiple items from a list, dict, etc
>>> from operator import itemgetter

>>> days
['mon', 'tue', 'wed', 'thurs', 'fri', 'sat', 'sun']
>>> f = itemgetter(5, 6)
>>> f(days)
('sat', 'sun')

>>> workouts
{'mon': 'chest+biceps', 'tue': 'legs', 'wed': 'cardio', 'thurs': 'back+triceps', 'fri': 'legs', 'sat': 'rest', 'sun': 'rest'}
>>> itemgetter('mon', 'tue')(workouts)
('chest+biceps', 'legs')

twitter icon more info
138

Much nicer to write our Bites in markdown, then just convert them into HTML with one simple command
(venv)
$ pip install markdown

$ more doc.md
## pybites

this is some markdown

here is a [link](http://example.com).

$ python -m markdown < doc.md > doc.html

$ more doc.html
<h2>pybites</h2>
<p>this is some markdown</p>
<p>here is a <a href="http://example.com">link</a>.</p>

twitter icon more info
137

Exception handling trick: "from None" suppresses the trace back for the ZeroDivisionError and the user only sees the Exception raised (thanks @JnyJny)
>> def x():
...     try:
...             1/0
...     except ZeroDivisionError:
...             raise Exception("Bad at math") from None
...
>>> x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in x
Exception: Bad at math

twitter icon more info
136

Use some #Django ORM magic to get the most common first names:
>>> from django.db.models import Count
>>> from django.contrib.auth.models import User

>>> User.objects.exclude(first_name__exact='').values(
...     'first_name').annotate(
...     name_count=Count('first_name')
... ).order_by('-name_count')[:5].values_list(
...     'first_name', flat=True
... )

<QuerySet ['David', 'Daniel', 'Michael', 'Chris', 'John']>

twitter icon more info
135

split("\n") can return odd results if you are using "\r\n" (Windows) or "\r" (Apple), use splitlines() which covers all (thanks @GeoffRiley)
>>> "first line\r\nsecond line".split("\n")
['first line\r', 'second line']
>>> "first line\r\nsecond line".splitlines()
['first line', 'second line']
>>> "first line\rsecond line".splitlines()
['first line', 'second line']
>>> "first line\nsecond line".splitlines()
['first line', 'second line']

twitter icon
134

#pandas tip: use apply and dateutil to easily convert a str to datetime for a whole column in your df:
>>> import pandas as pd
>>> df = pd.read_csv('pybites_users.csv')
>>> df.joined[0]
'2018-07-05 15:36:09'
>>> type(df.joined[0])
<class 'str'>
>>> import dateutil
>>> df.joined = df.joined.apply(dateutil.parser.parse)
>>> df.joined[0]
datetime.datetime(2018, 7, 5, 15, 36, 9)
>>> type(df.joined[0])
<class 'datetime.datetime'>

twitter icon more info
133

imageio makes it pretty easy to create simple GIFs in #Python
def create_gif(filenames, duration=DURATION):
    images = []
    for filename in filenames:
        images.append(imageio.imread(filename))
    imageio.mimsave(OUT_GIF, images, duration=duration)

twitter icon more info
132

How to pretty print (validate) JSON from CLI?
alias json='python -m json.tool'

twitter icon more info
131

To build Pythonic objects, observe how real Python objects behave. - Luciano Ramalho, Author of Fluent Python

twitter icon more info
130

Get rid of leading spaces in a multiline (doc)string using inspect.cleandoc
>>> readme = """
...   ## PyBites Code Archive
...
...   In this zipfile you will find a bunch of useful snippets.
... """
>>> readme
'\n  ## PyBites Code Archive\n\n  In this zipfile you will find a bunch of useful snippets.\n'
>>> print(readme)

  ## PyBites Code Archive

  In this zipfile you will find a bunch of useful snippets.
>>> from inspect import cleandoc
>>> print(cleandoc(readme))
## PyBites Code Archive

In this zipfile you will find a bunch of useful snippets.

twitter icon
129

Since Python 3.4 there is a more elegant way to work with file paths:
from pathlib import Path

tmp = Path('/tmp')
countries = tmp / 'countries.xml' 

if not countries.exists():
    ...

twitter icon
128

You can inspect objects in pdb with pp(vars(object)), to use help prepend an exclamation mark:
(Pdb) elem
<Element {http://www.worldbank.org}country at 0x106610908>
(Pdb) !help(elem)
Help on _Element object:
...

twitter icon
127

Remove duplicate names and title case them in one statement using a a set comprehension:
>>> names
['dana', 'tim', 'sara', 'ana', 'joyce', 'dana', 'time', 'ana']
>>> {name.title() for name in names}
{'Time', 'Sara', 'Ana', 'Dana', 'Tim', 'Joyce'}

twitter icon
126

You can create a dict using an iterable! Here is an example making a dict of node:port strings:
>>> nodes
['abcd:22', 'efgh:80', 'ijkl:443']
>>> dict(node.split(':') for node in nodes)
{'abcd': '22', 'efgh': '80', 'ijkl': '443'}

twitter icon
125

Use #Python requests and re.findall to get all Django articles on PyBites
>>> import re, requests
>>> html = requests.get('https://pybit.es/pages/articles.html').text
>>> matches = re.findall('(https://pybit.es/.*django.*html)', html)
>>> len(matches)
6
>>> matches[0]
'https://pybit.es/django-rest-tips-api-digital-ocean.html'
>>> matches[-1]
'https://pybit.es/learning-django.html'

twitter icon
124

Use #Python's isdigit in a list comprehension to extract numbers from of a string
>>> s = "pybites is 2 years and almost 3 months old"
>>> [int(word) for word in s.split() if word.isdigit()]
[2, 3]

twitter icon more info
123

In #Python you can use vars() to easily access the argparse Namespace
import argparse

parser = argparse.ArgumentParser(description='A simple calculator')
parser.add_argument('-a', '--add', nargs='+', help="Sums numbers")
parser.add_argument('-s', '--sub', nargs='+', help="Subtracts numbers")
parser.add_argument('-m', '--mul', nargs='+', help="Multiplies numbers")
parser.add_argument('-d', '--div', nargs='+', help="Divides numbers")
...
args = parser.parse_args()

# access argparse Namespace using vars:
(Pdb) for operation, numbers in vars(args).items(): (operation, numbers)
('add', None)
('sub', ['10', '7', '0.5'])
('mul', None)
('div', None)

twitter icon more info
122

Want to efficiently insert items into a list in sorted order? Use #Python's bisect
>>> items = [3]
>>> inserts = [5, 1, 7]
>>> from bisect import insort
>>> for i in inserts: insort(items, i)
>>> items
[1, 3, 5, 7]

twitter icon more info
121

Q: difference between __str__ and __repr__ in #Python? A: "My rule of thumb: __repr__ is for developers, __str__ is for customers." (Ned Batchelder on SO)

twitter icon more info
120

Use #numpy to perform calculations on arrays (by @leonardojvega)
>>> import numpy as np
>>> x = np.array([1, 2, 3, 4, 5])
>>> print(x * 2)
[2, 4, 6, 8, 10]
>>> print(x * x)
[1, 4, 9, 16, 25]

twitter icon
119

#Python what OS am I coding on today?
>>> import platform
>>> platform.system()
'Darwin'

twitter icon
118

In #Python you can use textwrap.dedent to remove any common leading whitespace from every line in text (thanks @brianokken)
def test():
    # end first line with \ to avoid the empty line!
    s = '''\
    hello
      world
    '''
    print(repr(s))          # prints '    hello\n      world\n    '
    print(repr(dedent(s)))  # prints 'hello\n  world\n'

twitter icon more info
117

Wow ... #Python's standard library keeps amazing us: comparing version numbers made easy:
>>> from distutils.version import StrictVersion
>>> StrictVersion('0.12.1') < StrictVersion('1.0.2')
True

twitter icon more info
116

#Python's infamous if __name__ == "__main__" statement and its mysterious powers explained by @thelynchpinau

twitter icon more info
115

#Python context manager for redirecting stdout:
from contextlib import redirect_stdout
from io import StringIO

f = io.StringIO()
with redirect_stdout(f):
    help(pow)
s = f.getvalue()

twitter icon more info
114

Wrap long strings over multiple lines to prevent PEP8's E501
s = ("this is my really, really, really, really, really, really, "  
     "really long string that I'd like to shorten.")

twitter icon more info
113

Reddit thread: "What does a person mean exactly when they describe code as pythonic?"

twitter icon more info
80

Listen to @_juliansequeira on the Test & Code podcast talk about our platform, the #100DaysOfCode, learning / teaching #Python, and our amazing community.

twitter icon more info
79

Let CLI arguments take precedence over defaults in #Python:
defaults = {'user': 'guest', ...}
parser = argparse.ArgumentParser()
... add args ...
cli_args = {k:v for k, v in vars(parser.parse_args()).items() if v}
combined = ChainMap(cli_args, defaults)

twitter icon more info
78

#Python itertools makes it easy to make a sequence starting a number:
>>> import itertools
>>> seq = itertools.count(10001)
>>> next(seq)
10001
>>> next(seq)
10002
>>> next(seq)
10003

twitter icon
77

#python calendar.monthcalendar returns a matrix of a month’s calendar:
>>> import calendar as cc
>>> from datetime import datetime as dt
>>> n = dt.now() # 2018.11
>>> cc.monthcalendar(n.year, n.month)
[[0, 0, 0, 1, 2, 3, 4], ..., [26, 27, 28, 29, 30, 0, 0]]

twitter icon
76

The ipaddress module simplifies various IP address related tasks
>>> import ipaddress as ip
>>> ip.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> my_ip = ip.ip_address('fe80:0:0:0:200:f8ff:fe21:67cf')
>>> my_ip
IPv6Address('fe80::200:f8ff:fe21:67cf')
>>> my_ip.version
6

twitter icon more info
75

In #Python you can do this for large numbers:
>>> foo = 123_456_789_012_345
>>> format(foo, ',')
'123,456,789,012,345'
>>>

twitter icon more info
74

Use #Python requests!
>>> import urllib.request as req
>>> url = 'https://pybit.es'
>>> req.urlopen(url).read()
...403
>>> r = req.Request(url)
>>> r.add_header('User-agent','wswp')
>>> req.urlopen(r).status
200

:)
>>> import requests
>>> requests.get(url).status_code
200

twitter icon
73

Functions are first-class objects with attributes in #Python
>>> def calculate_bmi(weight, length): 
... 
>>> calculate_bmi.__name__
'calculate_bmi'
>>> calculate_bmi.__doc__
'Given the weight and length, calculate BMI'
>>> calculate_bmi.__code__.co_varnames
('weight', 'length')

twitter icon
72

Two ways to strip punctuation from a string in #Python
>>> from string import punctuation as punc
>>> s = "punc;tu.ation!"
>>> table = str.maketrans({key: None for key in punc})
>>> line.translate(table)
'punctuation'
>>> ''.join([c for c in s if c not in punc])
'punctuation'

twitter icon
71

"Every great developer you know got there by solving problems they were unqualified to solve until they actually did it." - Patrick McKenzie

twitter icon
70

Use #requests_cache to cache requests to a remote API in #Python
import requests
import requests_cache

requests_cache.install_cache('my_cache')

twitter icon more info
69

"Code is like a piece of art; you're never quite finished with it." - @clamytoe

twitter icon
68

Use 'x' with open in #Python to write to a file that doesn't already exist (like bash's noclobber)
>>> with open('hello', 'w') as f:
...     f.write('hello')
...
>>> with open('hello', 'x') as f:
...     f.write('hello')
...
FileExistsError: [Errno 17] File exists: 'hello'

twitter icon
67

Interesting section from the #Python docs you might not have seen before: Design and History FAQ

twitter icon more info
66

"The Python Way" - origin of the Zen of Python

twitter icon more info
65

"Don't set out to learn Python. Choose a problem you're interested in and learn to solve it with Python." - @jakevdp

twitter icon
64

Ready to meet other passionate Pythonistas and talk more #Python? @pybites has a rich and diverse community on Slack! Head over to CodeChalleng.es and join ...

twitter icon
63

In #Python you can use print+join on a list, but look closer what the print function can do by itself ...
>>> row = ["1", "bob", "developer", "python"]
>>> print(','.join(str(x) for x in row))
1,bob,developer,python
>>> print(*row, sep=',')
1,bob,developer,python

twitter icon
62

Analyzing Brexit data with #Pandas #Python

twitter icon more info
61

10 guidelines that will make you write more maintainable software #Software #Programming #CodeQuality @sig_eu

twitter icon more info
60

Determine the version of #Python you are using from the command line and at runtime:
$ python -V
Python 3.6.1 :: Continuum Analytics, Inc.

>>> import sys
>>> if sys.version_info[0] < 3:
...     raise "Time to migrate to Python 3!"
...
>>> assert sys.version_info >= (3, 6)
>>>

twitter icon
59

Multiple comparisons in #Python? Just use "in":
>>> colors = 'blue red green yellow black white orange'.split()
>>> color = random.choice(colors)
# is this a primary color?
>>> color == 'red' or color == 'blue' or color == 'yellow'
True
>>> color in 'red yellow blue'.split():
True

twitter icon
58

You want to compare 2 sequences in #Python? set operations are your best friend:
>>> a = {1, 2, 3, 4, 5}  # or set() cast a list
>>> b = {1, 2, 3, 6, 7, 8}
# unique to a
>>> a - b
{4, 5}
# unique to b
>>> b - a
{8, 6, 7}
# in both sets
>>> a & b
{1, 2, 3}
# in either one or the other
>>> a ^ b
{4, 5, 6, 7, 8}

twitter icon
57

Use triple quotes in #Python to make a multiline string:
>>> msg = """Hello Tim,
...
... Thanks for your message.
...
... We ..."""
>>> msg
'Hello Tim,\n\nThanks for your message.\n\nWe ...'

twitter icon
56

The best way to keep your coding skills fresh is to practice every day. We made a #100DaysOfCode grid on our platform so you can stay on track- Always Be Coding

twitter icon more info
55

Given a list of friends how many pairs can be formed? #Python's itertools.combinations is your friend:
>>> friends = 'bob tim julian fred'.split()
>>> list(itertools.combinations(friends, 2))
[('bob', 'tim'), ('bob', 'julian'), ('bob', 'fred'), ('tim', 'julian'), ('tim', 'fred'), ('julian', 'fred')]

twitter icon
54

Use #Python itertools.cycle to loop through a sequence ad infinitum, you could use this for an animated spinner for example:
>>> symbols = itertools.cycle('-\|/')
>>> next(symbols)
'-'
>>> next(symbols)
'\\'
>>> next(symbols)
'|'
>>> next(symbols)
'/'
>>> next(symbols)
'-'

twitter icon more info
53

#Python's random, range and itertools.product make it easy to simulate 5 dice rolls:
>>> import random, itertools
>>> dice = range(1, 7)
>>> for _ in range(5):
...     random.choice([p for p in itertools.product(dice, repeat=2)])
...
(1, 6)
(6, 3)
(4, 1)
(1, 2)
(4, 3)

twitter icon
52

Use deepcopy to copy compound objects in #Python:
>>> from copy import deepcopy
>>> items = [dict(id=1, name='laptop')]
>>> items2 = deepcopy(items)
>>> items[0]['name'] = 'macbook'
>>> items
[{'id': 1, 'name': 'macbook'}]
>>> items2
[{'id': 1, 'name': 'laptop'}]  # name intact

twitter icon
51

PyBites take on How to Learn #Python

twitter icon more info
50

Look at live objects with #Python's inspect module, for example does my function use utc.localize?
>>> from timezone import what_time_lives_pybites as wt
>>> import inspect
>>> src = ''.join(inspect.getsource(wt))
>>> 'utc.localize' in src
True

twitter icon
49

How to inspect an object and getting help in #Python:
>>> a = 'hello'
>>> dir(a)
['__add__', ...a lot..., 'title', 'translate', 'upper', 'zfill']
>>> help(a.title)
Help on built-in function title:
..
    Return a titlecased version of S, i.e. words start with title case...

twitter icon
48

You like Unix calendar? #Python has it too :)
>>> import calendar
>>> calendar.month(2018, 4)
>>> print(calendar.month(2018, 4))
     April 2018
Mo Tu We Th Fr Sa Su
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30

twitter icon
47

Our #Python challenges repo has 1400+ forks and 400+ PRs (code submissions), we are stoked/ excited to have so many people coding with us, thanks! Bob & Julian

twitter icon more info
46

Starting #Python 3.5 (PEP 448) there is an elegant way to merge dictionaries:
>>> d1 = dict(bob=11, julian=22)
>>> d2 = dict(sara=33, carmen=44)
>>> {**d1, **d2}
{'bob': 11, 'julian': 22, 'sara': 33, 'carmen': 44}

twitter icon more info
45

In #Python you can return/unpack multiple values from a function:
>>> def func():
...     stdout = 'program output'
...     stderr = 'program errors'
...     return stdout, stderr
...
>>> out, err = func()
>>> out
'program output'
>>> err
'program errors'

twitter icon
44

Different ways to reverse a list in #Python: in-place, creating an iterator, slicing with negative step:
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers.reverse()
>>> numbers
[5, 4, 3, 2, 1]
>>> list(reversed(numbers))
[1, 2, 3, 4, 5]
>>> numbers
[5, 4, 3, 2, 1]
>>> numbers[::-1]
[1, 2, 3, 4, 5]

twitter icon
43

Use join in #Python to combine a list of multiple strings:
>>> output = ['this is a output', 'of my program', 'Python is awesome']
>>> print('\n'.join(output))
this is a output
of my program
Python is awesome

twitter icon
42

You need a unique ID in #Python? Use the uuid module:
>>> from uuid import uuid4
>>> uuid4()
UUID('fcbb0369-7bd9-464d-b23c-9622d40fdcda')
>>> uuid4()
UUID('3e8e68b4-172b-42db-bcf7-07c12e0c9660')

twitter icon
41

#Python comes with batteries included, need an HTTP server? No problem: python3 -m http.server

twitter icon
40

Give a number leading zeros in #Python using zfill:
>>> for i in range(8, 11):
...     str(i).zfill(3)
...
'008'
'009'
'010'

twitter icon
39

Useful way to check if all/any elements of an iterable are true in #Python:
>>> languages = ['Java', 'Perl', 'PHP', 'Python', 'JS', 'C++', 'JS', 'Ruby']
>>> all(len(l) >= 2 for l in languages)
True
>>> any('++' in l for l in languages)
True

twitter icon
38

Use a list comprehension in #Python to filter a list:
>>> languages = ['Python', 'Java', 'Perl', 'PHP', 'Python', 'JS', 'C++', 'JS', 'Python', 'Ruby']
>>> [l for l in languages if l.lower().startswith('p')]
['Python', 'Perl', 'PHP', 'Python', 'Python']

twitter icon
37

Need unique values from a list in #Python? Use a set:
>>> languages = 'Python Java Perl PHP Python JS C++ JS Python Ruby'.split()
>>> set(languages)
{'Perl', 'JS', 'Python', 'Ruby', 'Java', 'PHP', 'C++'}

twitter icon
36

2 ways to rotate a string by n characters in #Python: slicing and collections.deque
>>> s = 'hello'
>>> s[2:] + s[:2]
'llohe'
>>> from collections import deque
>>> d = deque(s)
>>> d.rotate(-2)
>>> d
deque(['l', 'l', 'o', 'h', 'e'])

twitter icon
35

Get a tweet's sentiment in #Python using Textblob:
>>> tw1 = "I was happy receiving your book in the mail"
>>> TextBlob(tw1).sentiment.polarity
0.8
>>> tw2 = "Too bad I was out all day not being able to code Python"
>>> TextBlob(tw2).sentiment.polarity
-0.09999999999999992

twitter icon
34

For counting in #Python look no further than collections.Counter:
>>> from collections import Counter
>>> languages = 'Python Java Perl Python JS C++ JS Python'.split()
>>> Counter(languages)
Counter({'Python': 3, 'JS': 2, 'Java': 1, 'Perl': 1, 'C++': 1})

twitter icon
33

Our #100DaysOfCode in #Python course is your perfect companion to take the 100 days of code challenge. You will learn a lot of Python technologies and libraries

twitter icon more info
32

Listen to Bob and Julian, how they started coding in #Python, their exciting PyBites journey and what they learned completing the #100DaysOfCode challenge

twitter icon more info
31

#Python makes it easy to pick a random sample of a sequence:
>>> names = 'bob julian tim sara carmen job martin vero'.split()
>>> from random import sample
>>> sample(names, 2)
['sara', 'julian']
>>> sample(names, 2)
['vero', 'job']

twitter icon
30

Flatten a list of lists with sum in #Python:
>>> sum([[1, 2], [3], [4, 5], [6, 7, 8]], [])
[1, 2, 3, 4, 5, 6, 7, 8]

twitter icon
29

Your best friend when debugging in #Python: import pdb; pdb.set_trace() and it gets better: 3.7 introduces the new breakpoint() built-in (PEP 553)

twitter icon more info
28

#Python (3.6) f-strings can embed variables and expressions:
>>> for i in range(3):
...     f'{i} apple{"s" if i != 1 else ""}'
...
'0 apples'
'1 apple'
'2 apples'

twitter icon
27

"Knowledge can't just be handed to you, it must be earned with time and effort." - Martin Uribe

twitter icon
26

Want to know how to code #Python on our platform? In this Bites of Py demo video we walk you through solving Bite 1. Sum n numbers

twitter icon more info
25

#Flask is a great framework to get your feet wet with web development in #Python, learn the basics in ~ 2 hours joining @_juliansequeira's Beginner Flask course

twitter icon more info
24

"The canonical 'Python is a great first language', elicited, 'Python is a great last language!'" - Noah Spurrier

twitter icon
23

"#Python is the most powerful language you can still read." - Paul Dubois

twitter icon
22

#Python Humor - a spurious collection of semi to totally unserious stuff

twitter icon more info
21

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." - Martin Fowler

twitter icon
20

"Always be the worst guy in every band you’re in. - so you can learn. The people around you affect your performance. Choose your crowd wisely.” - Chad Fowler

twitter icon
19

"Talk is cheap. Show me the code." - Linus Torvalds

twitter icon
18

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." – Martin Golding

twitter icon
17

"It’s not at all important to get it right the first time. It’s vitally important to get it right the last time.” - The Pragmatic Programmer

twitter icon
16

In #Python “is” checks that 2 arguments refer to the same object, == checks that they have the same value
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> c = a
>>> a == b
True
>>> a is b
False
>>> a == c
True
>>> a is c
True

twitter icon more info
15

In #Python you can chain comparison operators:
>>> a = 5
>>> b = 15
>>> 1 < a < 10
True
>>> 1 < b < 10
False

twitter icon
14

In #Python sorted/min/max take an optional key argument with callable
>>> ages = {'bob': 11, 'julian': 22, 'tim': 33}
>>> sorted(ages.items(), key=lambda x: x[1], reverse=True)
[('tim', 33), ('julian', 22), ('bob', 11)]

twitter icon more info
13

If you need the index inside a loop in #Python use enumerate
>>> names = 'bob julian tim sara'.split()
>>> for i, name in enumerate(names, 1):
...     print(i, name)
...
1 bob
2 julian
3 tim
4 sara

twitter icon more info
12

#Python offers a handy feature called tuple unpacking:
>>> first, *rest = [1, 2, 3, 4]
>>> first
1
>>> rest
[2, 3, 4]

twitter icon
11

String literals will concatenate in #Python:
>>> 'Python' ' is ' 'fun'
'Python is fun'

twitter icon
10

In #Python you can use the range builtin to generate a sequence of numbers
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

twitter icon more info
9

In #Python you can easily create a dict of two sequences using the zip builtin
>>> names = 'bob julian tim sara'.split()
>>> ages = '11 22 33 44'.split()
>>> dict(zip(names, ages))
{'bob': '11', 'julian': '22', 'tim': '33', 'sara': '44'}

twitter icon
8

An easy way to make a list in #Python is to use split() on a string which splits on space by default:
>>> names = 'bob julian tim sara'.split()
>>> names
['bob', 'julian', 'tim', 'sara']

twitter icon
7

Need to swap a 2 variables in #Python? No problemo, just 1 line of code:
>>> a = 1
>>> b = 2
>>> a, b = b, a
>>> a
2
>>> b
1

twitter icon
6

#Python has a for...else construct, else is reached if nothing breaks the for loop
>>> for i in range(10):
...     pass
... else:
...     print('reached')
...
reached

twitter icon more info
5

"I chose Python as a working title for the project, being in a slightly irreverent mood (and a big fan of Monty Python's Flying Circus)." - Guido van Rossum

twitter icon
4

"In December 1989, I was looking for a 'hobby' programming project that would keep me occupied during the week around Christmas" - Guido van Rossum

twitter icon
3

We love #Python ... type "import antigravity" in the REPL and fly with us!

twitter icon more info
2

Will #Python ever support braces?
>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance

twitter icon
1

What is #Python's philosophy? Run "import this" in the REPL

twitter icon more info
We use Python 3.7