Be agile: take back control over your work

779 views

Published on

When you have to manage tons of projects, several developers, challenging customers you need to re-think your organization.
Agile methodologies are the answer, but you also need tools to manage them.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
779
On SlideShare
0
From Embeds
0
Number of Embeds
65
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Be agile: take back control over your work

  1. 1. agile.open.connected Essere agili? Metodi, strumenti e integrazioni Python “to rule them all” Massimo Azzolini
  2. 2. Massimo Azzolini Founder - Project manager RedTurtle - Ferrara - Italy massimo@redturtle.it @massimoazzolini www.redturtle.it Massimo Azzolini Not an agile guru
  3. 3. being agile...
  4. 4. Massimo Azzolini The agile manifesto ➡ Individuals and interactions over processes and tools ➡ Working software over comprehensive documentation ➡ Customer collaboration over contract negotiation ➡ Responding to change over following a plan
  5. 5. 12 principles of agile manifesto
  6. 6. 1. Satisfy the customer 2. Welcome changing requirements 3. Deliver working software frequently 4. Business people and developers work together 5. Build projects around motivated individuals. 6. Face-to-face conversation 7. Working software is the primary measure of progress 8. Agile processes promote sustainable development 9. Attention to technical and design excellence 10. Simplicity is essential 11. The best architectures and requirements emerge from self-organizing teams 12. Retrospective 12 principles of agile manifesto
  7. 7. Kanban? Scrum?
  8. 8. Scrum
  9. 9. Kanban
  10. 10. so how can I make it USEFUL?
  11. 11. Massimo Azzolini The structure Started in 1999 in Ferrara, in 2012 we have had: ★ 14 people in house ★ most backend developers ★ 4 freelancer (not RedTurtle) ★ 3 teams ★ 77 projects ★ 347 customer requests ★ 1943 tickets solved ★ 20K+ hours worked
  12. 12. ISO 9001
  13. 13. no, I mean really USEF UL ?!
  14. 14. trainings and conferences
  15. 15. Scrum doesn’t completely fit to us Kanban doesn’t completely fit to us LOL
  16. 16. Massimo Azzolini What is left? 1. Teams 2. Iterations 3. Agile team to embrace the verb 4. Introduce 1-2 new tools/methods after every agile meeting 5. Multiple kanban boards (personal vs group vs project) 6. WIP limit and customers’ delays 7. Value your time 8. Write everything 9. Code review
  17. 17. Massimo Azzolini Which tools? ➡ Email?! ➡ Share Documents ‣ Google Drive ‣ Dropbox ➡ Organize tasks ‣ Trello o Kanbanery ‣ Simple management (or other plone based solutions) ‣ Basecamp
  18. 18. Penelope getpenelope.github.com
  19. 19. Project journey
  20. 20. A new project Google Documentation Project Manager Customer requests Trac Reports
  21. 21. Dashboard Google Documentation Customer Trac - tickets Trac - roadmap
  22. 22. Dashboard Trac Developer Time management Sentry Customer requests Time management
  23. 23. Show me the code!!!
  24. 24. OAuth/Login
  25. 25. Google OAuth2 example [app:penelope] ... pyramid.includes = velruse.providers.google provider.google.consumer_key = 441361239240193 provider.google.consumer_secret = 52ef2618a1999eeec6d9c provider.google.scope = https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/drive.apps.list wgsi.ini
  26. 26. GDrive integration
  27. 27. GDrive Integration @documents.auth_graceful def get_google_document(context, request, **kwargs):     try:        folder_entry = request.gclient['DocsClient'].get_doclist( uri='/feeds/default/private/full/%s/contents/' % folder_id) folder = folder_entry.entry     except (ValueError, RequestError), e:        status = u'''Something is not working correctly.'''     params.update(folder=folder, status=status)
  28. 28. Trac integration
  29. 29. TicketStore - Trac Integration class ITicketStore(Interface):     def get_tickets_for_project(self, project, request, query=None, limit=None):         """ """     def get_requests_from_tickets(self, project, ticket_ids, request=None):         """ """     def get_tickets_for_request(self, customer_request, limit=None, request=None):         """ """
  30. 30. Deform/Colander
  31. 31. Deform/Colander @view_config(renderer='templates/form.pt', name='myform') def myform(self): class Mapping(colander.Schema): name = colander.SchemaNode( colander.String(), description='Content name') date = colander.SchemaNode( colander.Date(), widget=deform.widget.DatePartsWidget(), description='Content date') class Schema(colander.Schema): number = colander.SchemaNode( colander.Integer()) mapping = Mapping() schema = Schema() form = deform.Form(schema, buttons=('submit',)) return self.render_form(form)
  32. 32. Deform/Colander
  33. 33. Mandrill
  34. 34. def send(self, from_addr, recipients, data):         # Ensure the message complies with RFC2822: use CRLF line endings         message = data['msg']         data = data['data']         params = {}         changes_body = data['changes_body']         if changes_body:             params['changes_body'] = rest2html(changes_body)         if data['ticket']['new']:             params['ticket_new'] = True         params['ticket_body_hdr'] = data['ticket_body_hdr']         params['ticket_link'] = data['ticket']['link']         params['ticket_reporter'] = data['ticket']['reporter']         params['ticket_owner'] = data['ticket']['owner']         params['ticket_description'] = self.wiki2html(data['ticket']['description'])         params['ticket_type'] = data['ticket']['type']         params['ticket_status'] = data['ticket']['status']         params['ticket_priority'] = data['ticket']['priority']         params['ticket_milestone'] = data['ticket'].get('milestone')         params['change_author'] = data['change'].get('author','')         params['change_comment'] = self.wiki2html(data['change'].get('comment','')) Mandrill
  35. 35. Sentry
  36. 36. Sentry-Penelope class PenelopePlugin(IssuePlugin):          def create_issue(self, request, group, form_data, **kwargs):         proxy = TracXmlProxy(form_data['trac'], request=request)         try:             opts = {'type': 'defect',                     'issuetype': 'sistemistica',                     'customerrequest': '',                     'owner': ''}             ticket = proxy.ticket.create(form_data['title'],                                          form_data['description'],                                          opts)         except Exception, e:             msg = unicode(e)             raise forms.ValidationError(_('Error communicating: %s') %(msg,))         try:             data = int(ticket)         except Exception, e:             raise forms.ValidationError(_('Error decoding response: %s') % (e,))         return data
  37. 37. Solr - trac full text search
  38. 38. Questions ? Massimo Azzolini RedTurtle’s co-founder and project manager massimo@redturtle.it tw: @massimoazzolini

×