Some notes & source-code from the talk given in TheJunction. Links to more source code & resources can be found at the bottom of this post.
Screencast recording
(not the actual talk, but almost identical):
- messages
- Python is great
- Django is great
- AppEngine is great
- but in order not to lock-in, use Django there
- shell
- מאפשר פיתוח אינטראקטיבי מהיר, בו הסייקל של כתיבה בדיקה והרצה מהיר ביותר
- exploratory coding
- מאפשר פיתוח אינטראקטיבי מהיר, בו הסייקל של כתיבה בדיקה והרצה מהיר ביותר
- Python overview
- shell
-
>>>
>>>
>>> x = 1
>>> x
1
>>> x == 1
True
>>>
>>>
>>> type(x)
<type 'int'>
>>>
>>>
>>> dir(x)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> x.imag()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> x.imag
0
>>>
>>>
>>> if x == 2:
... print "Yes"
... else:
... print "No"
...
No
>>> while x < 10:
... x += 1
... print x
...
2
3
4
5
6
7
8
9
10
>>>
>>> l = [1, 2, 3, 4]
>>> len(l)
4
>>> l.append("a")
>>> l
[1, 2, 3, 4, 'a']
>>> for x in l:
... print x
...
1
2
3
4
a
>>> t = (1, 2, 3, 4)
>>>
>>> len(t)
4
>>> t.append("a")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
>>>
>>>
>>>
>>>
>>>
>>> l * 2
[1, 2, 3, 4, 'a', 1, 2, 3, 4, 'a']
>>> l
[1, 2, 3, 4, 'a']
>>> l + [4, 5, 6]
[1, 2, 3, 4, 'a', 4, 5, 6]
>>>
>>>
>>>
>>> l2 = [x**2 for x in l if type(x) == int]
>>>
>>>
>>>
>>>
>>> 10**2
100
>>> l2
[1, 4, 9, 16]
>>> l2 = [x**2 for x in l]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
>>>
>>>
>>>
>>>
>>> def add(x, y):
... return x + y
...
>>>
>>> add(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(10, 12)
22
>>>
>>>
>>> def (*args):
File "<stdin>", line 1
def (*args):
^
SyntaxError: invalid syntax
>>> def add(*args):
... return sum(args)
...
>>> add(10)
10
>>> add(10, 20, 30)
60
>>>
>>>
>>> def add_and_multiply(x, y):
... return x + y, x * y
...
>>>
>>>
>>> add_and_multiply(10, 20)
(30, 200)
>>>
>>>
>>> a, b = add_and_multiply(10, 20)
>>>
>>>
>>> b
200
>>>
>>>
>>>
>>> class MyClass():
... def __init__(v):
...
File "<stdin>", line 3
^
IndentationError: expected an indented block
>>>
>>>
>>>
>>>
>>> class MyClass():
... def __init__(self, v):
... self.v = v
...
>>>
>>>
>>>
>>> x = MyClass(5)
>>>
>>>
>>> x
<__main__.MyClass instance at 0x39a670>
>>>
>>>
>>> dir(x)
['__doc__', '__init__', '__module__', 'v']
>>>
>>>
>>> x.v
5
>>>
>>>
>>>
-
- Python module
-
def add_and_multiply(x, y):
"""
Returns the sum & product of given 2 numbers
"""
return x + y, x * y
if __name__ == "__main__":
print add_and_multiply(10, 20)
-
- self in methods is derived from the python principle of:
- Explicit is better than implicit
- See the rest of the principles
- import this
- list comprehension
-
כפי ששפת אם משחררת את המחשבה, ומאפשרת לדבר במהירות, קצר, יפה וקולע
ככה גם פייתון
נגיד שיש לכם שתי רשימות של מספרים ואתם צריכים לחשב ממוצע של סכום כל 2 מספרים באותו מיקום ברשימות, במידה ושניהם גדולים מ-0
בכמה שורות תכתבו את זה בשפה שאתם מכירים?
בפייתון מספיקה 1
- sum([i+j for i, j in zip(l1, l2) if a*b>0]) / len(l1)
-
- פונקציה
-
- def add
- ניתן גם להחזיר יותר מערך אחד
- def add_and_multiply
- doctest
- על מנת לוודא שנכונות של פונקציות לא נשברת בריפקטורינג, חשוב לכתוב יוניט טסטס
- נניח שאנחנו רוצים להכין אחד לפונקציה שהכנו קודם
- קודם כל, בואו נבדוק קצת את הפונקציה בשל
- עכשיו נעתיק את הבדיקה הידנית לתוך הערה בהתחלת הפונקציה
-
-
def add_and_multiply(x, y):
"""
Returns the sum & product of given 2 numbers
>>> add_and_multiply(10, 20)
(30, 200)
>>>
>>> add_and_multiply(0, 0)
(0, 0)
>>>
>>> add_and_multiply(10, 0)
(10, 0)
>>>
>>> add_and_multiply(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add_and_multiply() takes exactly 2 arguments (1 given)
>>>
"""
return x + y, x * y
if __name__ == "__main__":
print add_and_multiply(10, 20)
doctest.testmod()
-
- shell
- Django overview
- installation
- django-admin.py
- commands
- manage.py
- PyCharm
- live templates
- debugging
- error highlighting
- django & appengine support
- AppEngine
-
- manage.py deploy
- will run syncdb & createsuperuser
- manage.py deploy
- code
- settings.py
-
# setup default datastore paths
_ds_pathinfo = {
'datastore_path': '../data/waybetter.datastore',
'history_path': '../data/waybetter.datastore.history',
}
DATABASES['gae'].update(_ds_pathinfo)
-
- urls.py
- url(r'^problem/(?P<problem_id>\d+)/$', 'haditbefore.views.view_problem'),
- (r'^_ah/xmpp/message/chat/', 'haditbefore.services.handle_message'),
- app.yaml
- Inbound services
-
- xmpp_message
- xmpp_presence
-
- Inbound services
- unit test
-
from django.test import TestCase
from django.test.client import Client
class SimpleTest(TestCase):
def test_basic_addition(self):
client = Client()
response = client.get("/")
self.assertEqual(len(response.context["problems"]), 2, "Expected 2 problems!")
-
- views
-
from django.http import HttpResponseNotFound, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template.context import RequestContext
from haditbefore_app.forms import ProblemForm
from haditbefore_app.models import Problem
def home(request):
problems = Problem.objects.all().order_by("-update_date")[:10]
return render_to_response('home.html', locals())
def view_problem(request, problem_id):
query = Problem.objects.filter(id=problem_id)
if query.count():
problem = query[0]
else:
return HttpResponseNotFound("No such problem")
return render_to_response('view_problem.html', locals())
def edit_problem(request, problem_id):
problem = get_object_or_404(Problem, id=problem_id)
form = ProblemForm(instance=problem)
if request.method == "POST":
form = ProblemForm(request.POST, instance=problem)
if form.is_valid():
form.save()
return HttpResponseRedirect("/")
return render_to_response('edit_problem.html', locals(), context_instance=RequestContext(request))
-
- settings.py
- indices problem
- high replication
- A problem with composite indexes, don't use it for now with django-nonrel
- high replication
- Links
- Books
- Python
-
- Tutorial given at PyCon (video at the bottom)
-
- Django
The Django Book 2 - AppEngine
- Python
- Documentation
- Google I/O 2011 Videos
-
- Had it before
- Source
- https://bitbucket.org/dibau/haditbefore/
-
- Had it before