1 / 11

When are projects due?

When are projects due?. #infomgmtFAIL This is why you never duplicate data. Project 4 is Due <WHEN THE WEBSITE SAYS SO> To get it done in time you will need to work smart, cut corners, and adjust rapidly. Use Rally's Burn-down charts to help you calibrate

Télécharger la présentation

When are projects due?

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. When are projects due? • #infomgmtFAIL • This is why you never duplicate data. • Project 4 is Due <WHEN THE WEBSITE SAYS SO> • To get it done in time you will need to work smart, cut corners, and adjust rapidly. • Use Rally's Burn-down charts to help you calibrate • Ask when >30mins of head-wall contact • Asking is nice even if you figure it out yourself • It does NOT need to be a website/phone app/etc. • Results > UX for project 4.

  2. Prototype with Google App Engine • Goal: Everyone gets to share one comment that is geotagged. Twitter-lite. • Get set up: • http://code.google.com/appengine/downloads.html • Everyone in your group!

  3. Web services 101 • Little "s" - bob • Everything is an ACTION to a URL with some PARAMETERS • http://yahoo.com/ • A "GET" to "/" with NO PARAMS • http://www.google.com/search?q=Hello+World • A "GET" to "/search" with ONE param (URL encoded) of q="Hello World" • <form method="POST" action="/new">… • POSTS you can't just type in the browser bar, but are normally form submits. Nice way to divide action from browsing. • Have a URL + a payload of name/value pairs (mostly) • Also PUT, DELETE and HEAD, but who cares…

  4. Google Datastore • Stuff you don't need to know • "Paxos algorithm" • "ancestor queries" • High availability, entity groups, bla bla bla • Stuff you do need to know • A little SQL • Basic idea of data types

  5. Build application = webapp.WSGIApplication([ ('/', MainPage) # ,('/sign', Guestbook) ], debug=True) def main(): run_wsgi_app(application) # http://pyfaq.infogami.com/tutor-what-is-if-name-main-for if __name__ == '__main__': main()

  6. User Management class MainPage(webapp.RequestHandler): def get(self): user = users.get_current_user() if user: self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, ' + user.nickname()) else: self.redirect(users.create_login_url(self.request.uri)) This is so much nicer than debating with the architect if your users should be indexed by email address, or their user ID, or a unique 11 digit integer, or off their DB AUTO_INCREMENT ID, or… bla.

  7. Knowing what was Posted def post(self): self.response.out.write('<html><body>You wrote:<pre>') self.response.out.write( cgi.escape(self.request.get('content')) ) self.response.out.write('</pre></body></html>')

  8. So what? Need to save it! class Tweet(db.Model): """Models an individual entry with an author, content, and date.""" author = db.UserProperty() content = db.StringProperty(multiline=True) date = db.DateTimeProperty(auto_now_add=True) …so nice not to be writing SQL create statements. And DB modeling. And all the other overhead. A prototyper could get spoiled with this…

  9. How to show a page of HTML? • Annoying way • self.response.out.write("""<form action="/sign?%s" method="post">… • Better way: path = os.path.join(os.path.dirname(__file__), 'index.html') self.response.out.write(template.render(path, template_values)) And every key in template_values maps to {{ key }}

  10. Actually Saving It # Still figuring this "parent" thing out. bhill def tweetbucket_key(): """Constructs a datastore key for tweet entities""" return db.Key.from_path('Tweets', 'default_tweetbucket') def post(self): new_tweet = Tweet(parent=tweetbucket_key()) if users.get_current_user(): new_tweet.author = users.get_current_user() new_tweet.content = self.request.get('content') new_tweet.put()

  11. Get back what you put in class AllPosts(webapp.RequestHandler): defget(self): tweets = db.GqlQuery("SELECT * " "FROM Tweet " "WHERE ANCESTOR IS :1" "ORDER BY date DESC LIMIT 100", tweetbucket_key()) result = [] # simple array for tweet in tweets: result.append({ 'author':tweet.author.nickname(), 'content':tweet.content, 'date':tweet.date.isoformat() }) # simple object appended to array content = simplejson.dumps(result) if callback: # JSON-P in 2 lines. content = cgi.escape(callback) +"(" + content + ")" self.response.headers.add_header('content-type', 'application/json', charset='utf-8') self.response.out.write(content)

More Related