Tumblelog by Soup.io
Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

April 27 2017

Python F-Strings Are Fun!

Python F-Strings Are Fun!

In python 3.6 we saw the adoption of Literal String Interpolation, or as they are known more commonly, f-strings. At first I was hesitant because... well... we've got multiple string tools already available:

one, two = 1, 2
_format = '{},{}'.format(one, two)
_percent = '%s,%s' % (one, two)
_concatenation = str(one) + ',' + str(two)
_join = ','.join((str(one),str(two)))
assert _format == _percent == _concatenation == _join

Adding f-strings to this mix didn't seem all that useful:

_fstring = f'{one},{two}'
assert _fstring == _format == _percent == _concatenation == _join

I was doubtful, but then I tried out f-strings on a non-trivial example. Now I'm hooked. Be it on local utility scripts or production code, I now instinctively gravitate toward their usage. In fact, f-strings are so useful that going back to earlier versions of Python now feels cumbersome.

The reason why I feel this way is that f-strings are concise but easy to understand. Thanks to intuitive expression evaluation I can compress more verbose commands into smaller lines of code that are more legible. Take a look:

_fstring = f'Total: {one + two}'  # Go f-string!
_format = 'Total: {}'.format(one + two)
_percent = 'Total: %s' % (one + two)
_concatenation = 'Total: ' + str(one + two)
assert _fstring == _format == _percent == _concatenation

The f-string example is four characters shorter than the closest alternative and is extremely easy to read. Indeed, put the f-string example in front of a non-programmer and they'll understand it fast. The same won't apply to the alternatives, odds are they'll ask what .format(), str(), and the % mean.

F-Strings Are Addictive

The conciseness and power of the intuitive expression evaluation can't be understated. On the surface f-strings seem like a small step forward for Python, but once I started using them I realized they were a huge step in codability for the language.

Now I'm hooked. I'm addicted to f-strings. When I step back to Python 3.5 or lower I feel like less of a Python coder. Yes, I have a problem with how much I lean on f-strings now, but I acknowledge my problem. I would go to therapy for it, but I believe I can manage the addiction for now.

Okay, enough joking, f-strings are awesome. Try them out.

A Utility Script Example

We just released Two Scoops of Django 1.11, which is written in LaTeX. Like most programming books we provide code examples in a repo for our readers. However, as we completey revised the code-highlighting, we had to rewrite our code extractor from the ground up. In a flurry of cowboy coding, I did so in thirty minutes using Python 3.6 while leaning on f-strings:

"""Two Scoops of Django 1.11 Code Extractor"""
import os
import shutil
from glob import glob

try:
    shutil.rmtree('code')
    print('Removed old code directory')
except FileNotFoundError:
    pass
os.mkdir('code')
print('Created new code directory')

STAR = '*'

LEGALESE = """LEGAL TEXT GOES HERE"""

LANGUAGE_START = {
    '\\begin{python}': '.py',
    '\\begin{badpython}': '.py',
    '\\begin{django}': '.html',
    '\\begin{baddjango}': '.html',
    '\\begin{plaintext}': '.txt',
    '\\begin{badplaintext}': '.txt',
    '\\begin{sql}': '.sql',
    '\\begin{makefile}': '',
    '\\begin{json}': '.json',
    '\\begin{bash}': '.txt',
    '\\begin{xml}': '.html',
}

LANGUAGE_END = {x.replace('begin', 'end'):y for x,y in LANGUAGE_START.items()}


def is_example(line, SWITCH):
    for key in SWITCH:
        if line.strip().startswith(key):
            return SWITCH[key]
    return None

def makefilename(chapter_num, in_example):
    return f'code/chapter_{chapter_num}_example_{str(example_num).zfill(2)}{in_example}'


if __name__ == '__main__':

    in_example = False
    starting = False
    for path in glob('chapters/*.tex'):
        try:
            chapter_num = int(path[9:11])
            chapter_num = path[9:11]
        except ValueError:
            if not path.lower().startswith('appendix'):
                print(f'{STAR*40}\n{path}\n{STAR*40}')
            continue
        example_num = 1
        with open(path) as f:
            lines = (x for x in f.readlines())
        for line in lines:
            if starting:
                # Crazy long string interpolation that should probably
                # be broken up but remains because it's easy for me to read
                filename =  f'code/chapter_{chapter_num}_example_{str(example_num).zfill(2)}{in_example}'
                dafile = open(filename, 'w')
                if in_example in ('.py', '.html'):
                    dafile.write(f'"""\n{LEGALESE}"""\n\n')
                else:
                    dafile.write(f'{LEGALESE}\n{STAR*20}\n\n')
                print(filename)
            if not in_example:
                mime = None
                in_example = is_example(line, LANGUAGE_START)
                if in_example:
                    starting = True
                continue
            mime = is_example(line, LANGUAGE_END)
            starting = False
            if mime:
                print(mime)
                in_example = False
                example_num += 1
                dafile.close()
            else:
                dafile.write(line)

April 26 2017

Python F-Strings Are Fun!

Python F-Strings Are Fun!

In python 3.6 we saw the adoption of Literal String Interpolation, or as they are known more commonly, f-strings. At first I was hesitant because... well... we've got multiple string tools already available:

one, two = 1, 2
_format = '{},{}'.format(one, two)
_percent = '%s,%s' % (one, two)
_concatenation = str(one) + ',' + str(two)
_join = ','.join((str(one),str(two)))
assert _format == _percent == _concatenation == _join

Adding f-strings to this mix didn't seem all that useful:

_fstring = f'{one},{two}'
assert _fstring == _format == _percent == _concatenation == _join

I was doubtful, but then I tried out f-strings on a non-trivial example. Now I'm hooked. Be it on local utility scripts or production code, I now instinctively gravitate toward their usage. In fact, f-strings so useful that going back to earlier versions of Python now feels cumbersome.

The reason why I feel this way is that f-strings are concise but easy to understand. Thanks to intuitive expression evaluation I can compress more verbose commands into smaller lines of code that are more legible. Take a look:

_fstring = f'Total: {one + two}'  # Go f-string!
_format = 'Total: {}'.format(one + two)
_percent = 'Total: %s' % (one + two)
_concatenation = 'Total: ' + str(one + two)
assert _fstring == _format == _percent == _concatenation

The f-string example is four characters shorter than the closest alternative and is extremely easy to read. Indeed, the f-string example in front of a non-programmer and they'll understand it fast. The same won't apply to the alternatives, odds are they'll ask what .format(), str(), and the % mean.

F-Strings Are Addictive

The conciseness and power of the intuitive expression evaluation can't be understated. On the surface f-strings seem like a small step forward for Python, but once I started using them I realized they were a huge step in codability for the language.

Now I'm hooked. I'm addicted to f-strings. When I step back to Python 3.5 or lower I feel like less of a Python coder. Yes, I have a problem with how much I lean on f-strings now, but I acknowledge my problem. I would go to therapy for it, but I believe I can manage the addiction for now.

Okay, enough joking, f-strings are awesome. Try them out.

A Utility Script Example

We just released Two Scoops of Django 1.11, which is written in LaTeX. Like most programming books we provide code examples in a repo for our readers. However, as we completey revised the code-highlighting, we had to rewrite our code extractor from the ground up. In a flurry of cowboy coding, I did so in thirty minutes using Python 3.6 while leaning on f-strings:

"""Two Scoops of Django 1.11 Code Extractor"""
import os
import shutil
from glob import glob

try:
    shutil.rmtree('code')
    print('Removed old code directory')
except FileNotFoundError:
    pass
os.mkdir('code')
print('Created new code directory')

STAR = '*'

LEGALESE = """LEGAL TEXT GOES HERE"""

LANGUAGE_START = {
    '\\begin{python}': '.py',
    '\\begin{badpython}': '.py',
    '\\begin{django}': '.html',
    '\\begin{baddjango}': '.html',
    '\\begin{plaintext}': '.txt',
    '\\begin{badplaintext}': '.txt',
    '\\begin{sql}': '.sql',
    '\\begin{makefile}': '',
    '\\begin{json}': '.json',
    '\\begin{bash}': '.txt',
    '\\begin{xml}': '.html',
}

LANGUAGE_END = {x.replace('begin', 'end'):y for x,y in LANGUAGE_START.items()}


def is_example(line, SWITCH):
    for key in SWITCH:
        if line.strip().startswith(key):
            return SWITCH[key]
    return None

def makefilename(chapter_num, in_example):
    return f'code/chapter_{chapter_num}_example_{str(example_num).zfill(2)}{in_example}'


if __name__ == '__main__':

    in_example = False
    starting = False
    for path in glob('chapters/*.tex'):
        try:
            chapter_num = int(path[9:11])
            chapter_num = path[9:11]
        except ValueError:
            if not path.lower().startswith('appendix'):
                print(f'{STAR*40}\n{path}\n{STAR*40}')
            continue
        example_num = 1
        with open(path) as f:
            lines = (x for x in f.readlines())
        for line in lines:
            if starting:
                # Crazy long string interpolation that should probably
                # be broken up but remains because it's easy for me to read
                filename =  f'code/chapter_{chapter_num}_example_{str(example_num).zfill(2)}{in_example}'
                dafile = open(filename, 'w')
                if in_example in ('.py', '.html'):
                    dafile.write(f'"""\n{LEGALESE}"""\n\n')
                else:
                    dafile.write(f'{LEGALESE}\n{STAR*20}\n\n')
                print(filename)
            if not in_example:
                mime = None
                in_example = is_example(line, LANGUAGE_START)
                if in_example:
                    starting = True
                continue
            mime = is_example(line, LANGUAGE_END)
            starting = False
            if mime:
                print(mime)
                in_example = False
                example_num += 1
                dafile.close()
            else:
                dafile.write(line)

April 25 2017

Two Scoops of Django 1.11 is Out!

Two Scoops of Django

When we started the Two Scoops of Django project back in 2012, I never thought it would become a book series. Well, it's turned into just that, and so I'm pleased to announce the "Early Release" or "BETA" release of the Two Scoops of Django: Best Practices for Django 1.11 PDF ebook.

Co-authored with Audrey Roy Greenfeld, the 1.11 edition of Two Scoops of Django is filled to the brim with knowledge to help make Django projects better. We introduce various tips, tricks, patterns, code snippets, and techniques that we've picked up over the years. What we didn't know or weren't certain about, once again we found the best experts in the world and asked them for the answers. Then we packed the result into a 530+ page book.

What's Next?

  • We'll be adding more material to the 1.11 edition in the near future, hence the term, "Early Release". Everyone who buys the 1.11 ebook from us gets all 1.11 ebook updates.
  • Once we're happy with the ebook, we'll release a print paperback edition, scheduled for May or June.
  • We're selling the book in PDF format, as well as taking pre-orders for the print edition.

Order

You can purchase the "Early Release" Two Scoops of Django: Best Practices for Django 1.11 PDF ebook at the Two Scoops Press store.

Two Scoops of Django 1.11 is Out!

Two Scoops of Django

When we started the Two Scoops of Django project back in 2012, I never thought it would become a book series. Well, it's turned into just that, and so I'm pleased to announce the "Early Release" or "BETA" release of the Two Scoops of Django: Best Practices for Django 1.11 PDF ebook.

Co-authored with Audrey Roy Greenfeld, the 1.11 edition of Two Scoops of Django is filled to the brim with knowledge to help make Django projects better. We introduce various tips, tricks, patterns, code snippets, and techniques that we've picked up over the years. What we didn't know or weren't certain about, once again we found the best experts in the world and asked them for the answers. Then we packed the result into a 530+ page book.

What's Next?

  • We'll be adding more material to the 1.11 edition in the near future, hence the term, "Early Release". Everyone who buys the 1.11 ebook from us gets all 1.11 ebook updates.
  • Once we're happy with the ebook, we'll release a print paperback edition, scheduled for May or June.
  • We're selling the book in PDF format, as well as taking pre-orders for the print edition.

Order

You can purchase the "Early Release" Two Scoops of Django: Best Practices for Django 1.11 PDF ebook at the Two Scoops Press store.

Newsletter #6

Welcome to the latest news about Two Scoops Press, Daniel Roy Greenfeld (pydanny), and Audrey Roy Greenfeld (audreyr).

Two Scoops of Django 1.11 Early Release Is Out

We just released the early release (BETA) of the fourth edition of Two Scoops of Django. This supports the Django 1.11 Long Term Support (LTS) release, which will be maintained until at least April of 2020. In late May, we plan to release the print paperback version. Today you can purchase the early release PDF as well as pre-order the print edition by itself or as a bundle with the PDF.

Two Scoops of Django 1.11 in our shop

If you have any questions, please read the Two Scoops of Django 1.11 FAQ.

Two Scoops Press Legacy Sale

For the first time since 2013, we're running a sale! We uncovered two boxes, one that contained several hardcover editions of Two Scoops of Django 1.6, and the other was a set of Two Scoops of Django 1.8 misprints (slight alignment oddities, minor cover coloration issues, or light scuffing). They are on sale for as long as our supplies last.

2015-2017 Python/Django Community Efforts

Here's a recap of our volunteer work since May of 2015.

Open Source

A number of the open-source projects that we maintain have reached important milestones.

  • Cookiecutter, the popular cross-platform project templating tool created by Audrey, is now supported by both PyCharm and Visual Studio. There are numerous tutorials about it in both video and written format. We would like to thank all the Cookiecutter contributors.
  • Cookiecutter Django, a Cookiecutter template for Django, is ow a Python 3-only project and will soon support Django 1.11. It comes with scripts for local installation of dependencies, as well as detailed instructions on deploying to Docker, Elastic Beanstalk, Python Anywhere, or Heroku instances.
  • cached-property, a decorator for caching properties in classes, now provides normal thread-safe decorators with time-to-expire options. To our delight, it's been influential in the discussions of including this capability in CPython itself!

Talks Given

  • PyCon North America 2016: We ran a booth for the Cookiecutter Project and led a four-day sprint for the project.
  • PyCon Singapore: PyDanny and Audrey gave a talk about writing libraries, Cookiecutter, and putting your open source out into the world.

Local Outreach

  • Django Girls Inland Empire: Audrey and Danny spoke at the first Riverside County, California Django Girls event.
  • DjangoGirls Ensenada: Audrey and Daniel went to the lovely town of Ensenada, Mexico to speak at the Django Girls event there.
  • Django Girls San Diego: Audrey and Daniel gave a talk at the first event of its kind in San Diego. 

Upcoming Books

Follow us on Twitter for updates on:

  • The print edition of Two Scoops of Django 1.11 will hopefully be out by late May.
  • Daniel is releasing three new fiction books within the next few months. Stay tuned!
  • Daniel is also planning to update Into the Brambles this year.

Thanks for reading, 

Daniel and Audrey Roy Greenfeld
codemakesmehappy.com
audreyr.com
danielroygreenfeld.com
pydanny.com

SSL/TLS Settings for Django

Let's make your Django project...

S3 Static & Media Files for Django

Using Amazon Web Services (AWS...

April 24 2017

The luxury of a creative community

The last few months of Evennia development have mainly focused around a series of very nice pull requests from a growing cadre of contributors. I have myself mainly been working away in Evennia's 'devel' branch which will lead up to Evennia 0.7.

Contributed goodness

People have put in a lot of good work to boost Evennia, both by improving fixing existing things and by adding new features (small selection). Thanks a lot everyone!
  • Contrib: Turn-based combat system - this is a full, if intentionally bare-bones implementation of a combat system, meant as a template to put in your particular game system into.
  • Contrib: Clothing sytem - a roleplaying mechanic where a character can 'wear' items and have this show in their descriptions. Worn items can also be layered to hide that underneath. Had plenty of opportunities for extensions to a given game.
  • Contrib: An 'event' system is in the works, for allowing privileged builders to add dynamic code to objects that fires when particular events happen. The PR is not yet merged but promises the oft pondered feature of in-game coding without using softcode (and notably also without the security of softcode!). 
  • A lot of PRs, especially from one user, dealt with cleanup and adherence to PEP8 as well as fixing the 'alerts' given by LGTM on our code (LGTM is by the way a pretty nifty service, they parse the code from the github repo without actually running it. The result is cleaner code and it also found some edge-cases here and there not covered by unit tests. The joint effort has brought us down from some 600+ alerts to somewhere around 90 - the remaining ones are alerts which I don't agree with or which are not important enough to spend effort on). 
  • The help mechanics of Evennia was improved by splitting up the default help command into smaller parts, making it easier to inject some changes to your help system without completely replacing the default one. 
  • Evennia's Xterm256 implementation was not correctly including the additional greyscale colors, those were added with new tags |=a ... |=z 
  • Evennia has the ability to relay data to external services through 'bots'. An example of this is the IRC bot, which is a sort of 'player' that sits in an in-game channel and connects that to a counterpart-bot sitting in a remote IRC channel. It allows for direct game-IRC communication, something enjoyed by people in the Evennia demo for many years now. The way the bot was defined used to be pretty hard-coded though. A crafty contributor changed that though, but incorporating the bot mechanism into Evennia's normal message flow. This allows for adding new types of bots or extending existing ones without having to modify Evennia's core. There is already an alternative IRC bot out there that represents everyone in the IRC room as a room full of people in the MUD. 
  • Evennia's Attributes is a database table connected to other objects via an ForeignKey relation. This relation is cached on the object. Some users however found that for certain implementations, such as using Attributes for large coordinate systems, no-matches (that is, a failed Attribute lookup on an object) can also be cached and leads to dramatic speed increases for those particular use cases. You live and learn.
  • Another contributor helped inprove the EvEditor (Evennia's VIM-like in-game text editor) by giving it a code-mode for editing Python code in-game with auto-indents and code execution. Jump into the code mode with the command @py/edit.
  • Time scheduling is another feature that has been discussed now and then and has now been added through a PR. This means that rather than specifying 'Do this in 400 seconds' you could say 'do this at 12AM, in-game time'. The core system works with the real-world time units. If you want 10 hours to a day or four weeks to a month the same contributor also made an optional calendar contrib for that!
  • A new 'whisper' command was added to the Default cmdset. It's an in-game command for whispering to someone in the same room without other people hearing it. This is a nice thing to have considering out-of-the-box Evennia is pretty much a 'talker'.
  • Lots of bug fixes big and small!
  • Some at_* hooks were added, such as at_give(giver, getter). This allows for finer control of the give process without handling all the logics at the command level. There are others hooks in the works but those will not be added until in Evennia 0.7. 
About that Evennia 0.7 ...

So while PRs are popping up left and right in master I've been working in the devel branch towards what will be the Evennia 0.7 release. The branch is not ready for public consumption and testing yet since it's still very much in flux. But tentatively it's about halfway there as I am slowly progressing through the tickets. Most of the upcoming features were coveredin the previous blog post so I'll leave it at that.

I just want to end by saying that it's a very luxurious (and awesome) feeling for me to see master-branch Evennia expand with lots of new stuff "without me" so to speak. The power of Open Source!
  

Image from http://maxpixel.freegreatpicture.com, released as public domain.

April 23 2017

Django Framework Nedir?

Web Programçılığı Web sayfalarının giderek yaygınlaşması ve kullanıcı ile etkileşmeye ihtiyacının olması nedeniyle CGI(Common Gateway Interface) ile başladığını söyleyebiliriz. CGI yönetemi ile etkileşimli web sayfaları üretmek oldukça pahalı bir iştir. Çünkü sunucuya CGI programının yapacağı her istek geldiğinde, program çalıştırılır. Dış program derlemeli bir dil ile yazılmış veya yorumlanabilir bir dil ile yazılmış olabilir. Yazılımın...

Django Framework Nedir? yazısı ilk önce Python Türkiye üzerinde ortaya çıktı.

Testing django template tags

In this blog post I will give you simple example how to test your template tags in django using django testing tools. Let's get started!

How to test templatetags?

Let say that you got this template tag under /templatetags/create_header.py in django:

from django import template

register = template.Library()


@register.inclusion_tag('example.html', takes_context=True)
def make_header(context):
    return {
        'header_title': context['title']
    }

This make_header tag will take the title from context and pass it template tag. Right after that example.html will be rendered.

If you want to test if this template tag works you can use this:

from django.test import SimpleTestCase
from django.template import Context, Template


class CreateHeaderTemplateTagTest(SimpleTestCase):

    def test_rendered(self):
        context = Context({'title': 'my_title'})
        template_to_render = Template(
            '{% load create_header %}'
            '{% make_header %}'
        )
        rendered_template = template_to_render.render(context)
        self.assertInHTML('<h1>my_title</h1>', rendered_template)

What is happening here? I setup Context instance with a proper variable that will be taken by templatetag. After that I create Template. I used the same syntax to include templatetags inside your html files - they are templates for Django.

Below I render a template with context and check if my templatetag renders correctly.

And that's all! I have my templatetag tested. Feel free to comment!

Cover image from Unsplash under CC0.

April 21 2017

Django ORM operations compared with Peewee

I saw a post in my weekly Python newsletter showing Django users how to execute common queries using SQLAlchemy. Here's the Peewee version.

Setup

Assume we have a Django model that looks like the following:

class Country(models.Model):
    name = models.CharField(max_length=255, unique=True)
    continent = models.CharField(max_length=50)

In Peewee, our table definition looks almost identical:

from peewee import *  # Peewee defines __all__, so import * is common practice.


class Country(Model):
    name = CharField(unique=True)  # Default max_length of 255.
    continent = CharField(max_length=50)

Because Peewee does not have a singleton, application-wide database configuration, we also need to associate our model with a database. A common convention, when working with more than one table, is to define a base Model class which configures the database. This will save you a lot of typing when you have more than one model:

from peewee import *
from playhouse.pool import PooledPostgresqlDatabase


db = PooledPostgresqlDatabase('my_app')


class BaseModel(Model):
    class Meta:
        database = db


class Country(BaseModel):
    name = CharField(unique=True)  # Default max_length of 255.
    continent = CharField(max_length=50)

To create tables, call the db.create_tables() method, passing in a list of tables. Peewee will re-order the tables so that they are created in the correct order if you have foreign-keys.

def create_tables():
    db.connect()
    db.create_tables([Country])
    db.close()  # Ensure we don't leave dangling connections.

Basic SELECTs

With Peewee, fetching all columns for all Countries looks like this:

countries = Country.select()
for country in countries:
    print country.name, 'is on', country.continent

With Django it looks quite similar:

countries = Country.objects.all()
for country in countries:
    print country.name, 'is on', country.continent

With Peewee, to select only the name of the country:

countries = Country.select(Country.name)
for country in countries:
    print country.name

The Django way is fairly similar, but behind-the-scenes it also selects the id column:

countries = Country.objects.only('name')

Filtering results using the WHERE clause

With Peewee, fetching only the name of countries in Europe, we write:

countries = Country.select(Country.name).where(Country.continent == 'Europe')

Django uses a keyword-argument hack:

countries = Country.objects.filter(continent='Europe').values('name')

More advanced filtering

If we want to find countries in Europe or Asia:

countries = (Country
             .select(Country.name)
             .where((Country.continent == 'Europe') |
                    (Country.continent == 'Asia')))

# Using "IN"
countries = (Country
             .select(Country.name)
             .where(Country.continent.in_(['Europe', 'Asia'])))

With Django, we introduce a special object called "Q":

from django.db.models import Q

countries = Country.objects.filter(Q(continent='Europe') |
                                   Q(continent='Asia'))

# Using "IN"
countries = Country.objects.filter(continent__in=['Europe', 'Asia'])

Grouping results

We want to get the number of countries per continent:

num_countries = fn.COUNT(Country.name).alias('count')
query = (Country
         .select(Country.continent, num_countries)
         .group_by(Country.continent))
for result in query:
    print '%s has %d countries' % (result.continent, result.count)

With Django we need to import a special "Count" function helper. The rows returned are dictionaries instead of model instances:

from django.db.models import Count

query = Country.objects.values('continent').annotate(count=Count('name'))
for result in query:
    print '%s has %d countries' % (result['continent'], result['count'])

Sorting rows

We want to get a list of countries, ordered by continent, then by name:

query = Country.select().order_by(Country.continent, Country.name)

With Django we use strings to reference the columns we're sorting by (this makes it more difficult to spot errors at runtime -- we'll get a strange SQL error if we make a typo, whereas Peewee will throw an AttributeError indicating the field is not valid).

query = Country.objects.all().order_by('continent', 'name')

Conclusion

Peewee maps more closely to SQL concepts, and it is internally consistent in its representation of tables, columns and functions. With Peewee, combining fields and functions follows predictable patterns. Django requires the use of special methods, special objects (like Q, Count and F), and has different semantics -- sometimes you must use keyword arguments, other times you use strings. Furthermore, those familiar with SQL will find themselves wondering how to translate a query into "Django" whereas with Peewee the APIs are very similar to their SQL counterparts. Although, as the author of Peewee, I'm probably a little biased in its favor.

For more thoughts on the poorly-designed Django ORM, check out Shortcomings in the Django ORM.

To learn more about Peewee, check out the quick-start guide or view an example Twitter-like site written using Peewee and Flask.

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

April 20 2017

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

April 19 2017

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

Python PIP local cache

Python PIP local cache

PIP is the Python Package Manager that allows Python developers and users to easily install Python packages published on the pip remote register by other developers .

If you are using the pip manager frequently then you may find this quick tip useful ,where I'll show how you can activate or enable the local cache of pip which is going to boost the download speed of pip packages .

The idea behind the pip cache is simple ,when you install a Python package using pip for the first time ,it gets saved on the cache .If you try to download/install the same version of the package on a second time ,pip will just use the local cached copy instead of retrieving it from the remote register .

Enabling the local cache of pip

Enabling the local cache of pip is fairly simple so let's do it step by step .

First open the pip configuration file located at ~/.pip/pip.conf with your preferred text editor .

vim ~/.pip/pip.conf

Then copy and add this

[global]
download-cache=/usr/local/pip/cache

Next create the folder

mkdir -p /usr/local/pip/cache

Then give it write access

chmod -R 755 /usr/local/pip/cache

You can instead use your profile config file ~/.bash_profile

So open ~/.bash_profile .

And add

export PIP_DOWNLOAD_CACHE=$HOME/.pip_download_cache

That is it ! I hope this was helpful for you .

April 18 2017

Python and Django Beginner's Pack: books, tutorials, newsletters

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

April 17 2017

Recap of DjangoConEurope 2017

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

April 16 2017

Increment has launched.

If you haven't already taken a look, first take a quick trip over to increment.com and take a look at Increment's first issue, covering how any company can set up and succeed at on-call rotations.

Over the past three months, I've had the fairly rare opportunity to watch Susan, Mercedes and Philipp transform Increment from a rought concept into something concrete (there are printed copies!).

It's been educational. Also, impressive.

Having never seen a magazine launch before, I would have never imagined the sheer weight of details. Putting together a style guide. Drafting a process for procuring artwork. Determining the quantity of artwork to include. Picking a number of articles for each issue, and the mix between staff contributions and industry contributions (especially for a first issue, as an unproven concept). Projecting a completion rate for external contributions, and consequently the factor of requested pieces beyond the minimum quantity.

Then comes the process of creating the content itself. The number of emails, phone calls and reach outs to gather background information. Determining the content calendar. Picking the article topics, and adapting them as the requested articles veer into unplanned directions. Determining a defined voice (for reasons I still find suspicious my proposal of writing in the voice of "tech david attenborough" didn't receive the adoption I hoped for).

Somehow Susan was able to navigate all of that, and much more, and willed this thing into existence. I'm proud of the first issue, and even more excited about what is coming down the pipe.

Overall, this project also does a pretty good job of illustrating why I remain so excited about Stripe: it's retained it's ability to run a few interesting experiments, while also focusing the majority of its work on the core mission.

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.

Don't be the product, buy the product!

Schweinderl