Your SlideShare is downloading. ×

Be agile: take back control over your work

409

Published on

When you have to manage tons of projects, several developers, challenging customers you need to re-think your organization. …

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
409
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. agile.open.connected Essere agili? Metodi, strumenti e integrazioni Python “to rule them all” Massimo Azzolini
  • 2. Massimo Azzolini Founder - Project manager RedTurtle - Ferrara - Italy massimo@redturtle.it @massimoazzolini www.redturtle.it Massimo Azzolini Not an agile guru
  • 3. being agile...
  • 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. 12 principles of agile manifesto
  • 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. Kanban? Scrum?
  • 8. Scrum
  • 9. Kanban
  • 10. so how can I make it USEFUL?
  • 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. ISO 9001
  • 13. no, I mean really USEF UL ?!
  • 14. trainings and conferences
  • 15. Scrum doesn’t completely fit to us Kanban doesn’t completely fit to us LOL
  • 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. Massimo Azzolini Which tools? ➡ Email?! ➡ Share Documents ‣ Google Drive ‣ Dropbox ➡ Organize tasks ‣ Trello o Kanbanery ‣ Simple management (or other plone based solutions) ‣ Basecamp
  • 18. Penelope getpenelope.github.com
  • 19. Project journey
  • 20. A new project Google Documentation Project Manager Customer requests Trac Reports
  • 21. Dashboard Google Documentation Customer Trac - tickets Trac - roadmap
  • 22. Dashboard Trac Developer Time management Sentry Customer requests Time management
  • 23. Show me the code!!!
  • 24. OAuth/Login
  • 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. GDrive integration
  • 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. Trac integration
  • 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. Deform/Colander
  • 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. Deform/Colander
  • 33. Mandrill
  • 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. Sentry
  • 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. Solr - trac full text search
  • 38. Questions ? Massimo Azzolini RedTurtle’s co-founder and project manager massimo@redturtle.it tw: @massimoazzolini

×