Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PythonIn Large Companies?<br />SébastienTandel<br />sebastien.tandel@corp.terra.com.br<br />sebastien.tandel@gmail.com<br />
Plan<br />About Terra<br />The 7 steps<br />Prototype<br />Define the Goals<br />Integration<br />Some Libs<br />Prove It ...
About Terra : Web Portal<br />Largest Latin American web portal<br />Located in 18 countries<br />1000s of servers<br />Br...
About Terra<br />Source: Nielsen NetView (June 2009)<br />
About Terra : Email Plaftorm<br />I’m part of the email team.<br />Some stats : <br />+10M mailboxes<br />+30M inbound ema...
About Terra<br /><ul><li>Several “official” languages at Terra :</li></ul>PHP, C, C++, Java, C#, Erlang<br /><ul><li>Avera...
No official “scripting” language (Python, Perl or other)</li></ul>Why? From what I hear<br />Performance<br />Integration ...
Flash Python Overview<br />Python is …<br />Interpreted<br />Dynamically Typed<br />Really Concise<br />Multi-paradigm : p...
Step 1 : Prototype<br />
Step 1 : Prototype<br />Buggy system re-written as prototype in Python<br />Surprise! Worked a lot better than its C cousi...
Step 1 : Prototype<br />Introducing new ideas is a long and though way<br />
Step 2 : Define the Goals<br />Performance critical systems : <br />postfix, lmtp, imap / pop<br />
Step 2 : Define the Goals<br /><ul><li>Performance critical systems</li></ul>Web-based systems<br />Webmail, ECP<br />
Step 2 : Define the Goals<br /><ul><li>Performance critical systems
Web-based systems</li></ul>Backend systems :<br />spamreporter, cleaner, clx trainer, base trainer, mfsbuilder, migrador, ...
Step 2 : Define the Goals<br /><ul><li>Performance critical systems
Web-based systems
Backend systems</li></ul>Almost inexistent systems (though interesting ones) :<br />Mailboxes stats, logs analysis (stats ...
Step 2 : Define the Goals<br /><ul><li>Performance critical systems
Web-based systems
Backend systems
Stats / User behavior characterization, …</li></ul>System / Integration tests scripts<br />
Step 2 : Define the Goals<br /><ul><li>Performance critical systems
Web-based systems
Backend systems
Stats / User behavior characterization, …
System / Integration tests scripts</li></ul>The Grail :<br /><ul><li>Python can be used for ALL except Performance Critica...
Step 3 : Integration<br />Python could be used with every systems<br />but how can I interface with the homemade systems (...
Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API: the “hard” way<br />
Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API: the “hard” way<br />swig : the lazy w...
Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API : the “hard” way<br />swig : the lazy ...
Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API : the “hard” way<br />swig : the lazy ...
Step 3 : Integration<br />Wrote bindings to interface with all major internal systems (thanks to ctypes)<br />With pythoni...
Step 3 : Integration<br />  from trrauth import TrrAuth<br />auth = TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”,...
Step 3 : Integration<br />  from trrauth import TrrAuth<br />auth = TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”,...
Step 3 : Integration<br />  from trrauth import TrrAuth<br />auth= TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”, ...
Step 4 : Some Libs<br />
Step 4 : Some LibsMaster / Slave<br />Master responsible for :<br />Forking the slaves<br />Reading a “list” of tasks<br /...
Step 4 : Some LibsMaster / Slave<br />One neat characteristic :<br />System might got bug in prod w/ minimal impact<br />I...
from robustpools.process_pool import master_task_list<br />from robustpools.process_pool import slave_task_list<br />m_con...
Step 4 : Some LibsTCP Sockets Pool<br />Manage connections to a pool of servers<br />send in a round-robin/priority way to...
Step 5 : Prove It Works<br />
Step 5 : Prove It Works<br />Prove = collect data … How?<br />Write integrated systems using bindings and libs of previous...
Step 5 : Prove It Works<br />Performance, one obvious thought : C/C++<br />PINCS<br />Performance is not C, Stupid!<br />
Step 5 : Prove It WorksPerformance<br />Some of the rewrites works faster than C/C++ cousins<br />Why?<br />OS / Systems l...
Step 5 : Prove It WorksProductivity<br />BTW, pure performance so important?<br />Time to Market much more important<br />...
Step 5 : Prove It WorksProductivity<br />http://page.mi.fu-berlin.de/prechelt/Biblio/jccpprt2_advances2003.pdf<br />
Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
Step 5 : Prove It WorksProductivity<br />
Step 5 : Prove It WorksProductivity<br />Some existing C/C++ systems re-written in Python<br />Original C/C++ versions tot...
Step 5 : Prove It WorksProductivity<br />Oh, parsing an email?<br />Any idea in C/C++?<br />
Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email</li></ul>from email import message_from_file<br />fh = o...
Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email</li></ul>content types of parts?<br />Any idea in C/C++ ...
Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
content types of parts</li></ul>from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, ...
Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
content types of parts
getting headers?
Any idea in C/C++?</li></ul>from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, “r”)...
Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
content types of parts
getting headers
Python libs are just that simple!</li></ul>… and there are a lot!<br />from email import message_from_file<br />def get_ma...
Step 5 : Prove It WorksPerformance (Again?)<br />For equivalent architecture <br />(libs, algorithm, infrastructure)<br />...
Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br />PINCS! : think first to architecture!<br />
Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!...
Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!
Ctypes : absurdly easy python bindings</li></ul>Cython: write python, obtain a gcc compiled lib<br />
Upcoming SlideShare
Loading in …5
×

Python For Large Company?

2,664 views

Published on

Companies in the process of adoption of a language evaluate several aspects like :
* performance
* integration with existing ecosystem
* productivity
* use case of this language
In this presentation, we'll focus e think about these points sharing the experience of the integration of Python at Terra.

Published in: Technology, Education
  • Login to see the comments

Python For Large Company?

  1. 1. PythonIn Large Companies?<br />SébastienTandel<br />sebastien.tandel@corp.terra.com.br<br />sebastien.tandel@gmail.com<br />
  2. 2. Plan<br />About Terra<br />The 7 steps<br />Prototype<br />Define the Goals<br />Integration<br />Some Libs<br />Prove It Works<br />Evangelize<br />Next Steps<br />Conclusions<br />
  3. 3. About Terra : Web Portal<br />Largest Latin American web portal<br />Located in 18 countries<br />1000s of servers<br />Brazil :<br />~7M unique visitors / day<br />~70M pageviews / day<br />
  4. 4. About Terra<br />Source: Nielsen NetView (June 2009)<br />
  5. 5. About Terra : Email Plaftorm<br />I’m part of the email team.<br />Some stats : <br />+10M mailboxes<br />+30M inbound emails per day<br />+30M outbound emails per day<br />avg : 300 mail/s, peak : 600 mail/s<br />Systems<br />Main systems : SMTP, LMTP, POP, IMAP, Webmail<br />Total of +30 systems to design/develop/maintain<br />Main languages used C / C++<br />
  6. 6. About Terra<br /><ul><li>Several “official” languages at Terra :</li></ul>PHP, C, C++, Java, C#, Erlang<br /><ul><li>Average # is one per team!
  7. 7. No official “scripting” language (Python, Perl or other)</li></ul>Why? From what I hear<br />Performance<br />Integration with others systems (& legacy)<br />Costs / benefits?<br />Buzzword fear<br />Labor market<br />
  8. 8. Flash Python Overview<br />Python is …<br />Interpreted<br />Dynamically Typed<br />Really Concise<br />Multi-paradigm : procedural, OO, functional<br />Exceptions : helpful for robustness, debug (no strace ;))<br />Garbage Collector : don’t worry about allocation/free<br />
  9. 9. Step 1 : Prototype<br />
  10. 10. Step 1 : Prototype<br />Buggy system re-written as prototype in Python<br />Surprise! Worked a lot better than its C cousin<br />Prototype is now in production!<br />Spread the word about this rewrite around me<br />Some technical people liked the idea<br />One has not been so enthusiast … my manager<br />Cons: <br />no integration with homemade systems<br />Just one example<br />
  11. 11. Step 1 : Prototype<br />Introducing new ideas is a long and though way<br />
  12. 12. Step 2 : Define the Goals<br />Performance critical systems : <br />postfix, lmtp, imap / pop<br />
  13. 13. Step 2 : Define the Goals<br /><ul><li>Performance critical systems</li></ul>Web-based systems<br />Webmail, ECP<br />
  14. 14. Step 2 : Define the Goals<br /><ul><li>Performance critical systems
  15. 15. Web-based systems</li></ul>Backend systems :<br />spamreporter, cleaner, clx trainer, base trainer, mfsbuilder, migrador, nnentrega, smigol, …<br />
  16. 16. Step 2 : Define the Goals<br /><ul><li>Performance critical systems
  17. 17. Web-based systems
  18. 18. Backend systems</li></ul>Almost inexistent systems (though interesting ones) :<br />Mailboxes stats, logs analysis (stats and user behavior characterization)<br />
  19. 19. Step 2 : Define the Goals<br /><ul><li>Performance critical systems
  20. 20. Web-based systems
  21. 21. Backend systems
  22. 22. Stats / User behavior characterization, …</li></ul>System / Integration tests scripts<br />
  23. 23. Step 2 : Define the Goals<br /><ul><li>Performance critical systems
  24. 24. Web-based systems
  25. 25. Backend systems
  26. 26. Stats / User behavior characterization, …
  27. 27. System / Integration tests scripts</li></ul>The Grail :<br /><ul><li>Python can be used for ALL except Performance Critical Systems</li></li></ul><li>Step 3 : Integration<br />
  28. 28. Step 3 : Integration<br />Python could be used with every systems<br />but how can I interface with the homemade systems (legacy) ? <br />
  29. 29. Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API: the “hard” way<br />
  30. 30. Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API: the “hard” way<br />swig : the lazy way <br />won’t create a Pythonic API for you<br />
  31. 31. Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API : the “hard” way<br />swig : the lazy way<br />ctypes: the stupidly easy way<br />from ctypes import cdll<br />l = cdll.LoadLibrary(“libc.so.6”)<br />l.mkdir(“python-mkdir-test”)<br />
  32. 32. Step 3 : Integration<br />Various way to create Python Bindings :<br />Python C API : the “hard” way<br />swig : the lazy way <br />ctypes : the stupidly easy way<br />Cython : write python, compile with gcc<br />
  33. 33. Step 3 : Integration<br />Wrote bindings to interface with all major internal systems (thanks to ctypes)<br />With pythonic API! <br />
  34. 34. Step 3 : Integration<br /> from trrauth import TrrAuth<br />auth = TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”, “terra”)<br />auth.attributes = [ “short_name”, “id_perm”, “antispam” ]<br />
  35. 35. Step 3 : Integration<br /> from trrauth import TrrAuth<br />auth = TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”, “terra”)<br />auth.attributes = [ “short_name”, “id_perm”, “antispam” ]<br /> print auth.short_name, “:”, auth.id_perm<br />
  36. 36. Step 3 : Integration<br /> from trrauth import TrrAuth<br />auth= TrrAuth(“IMAP”)auth.open_userpass(“standel”, “1q2w3e”, “terra”)<br />auth.attributes = [ “short_name”, “id_perm”, “antispam” ]<br />for attr, value in auth:  print attr, “:”, value<br />
  37. 37. Step 4 : Some Libs<br />
  38. 38. Step 4 : Some LibsMaster / Slave<br />Master responsible for :<br />Forking the slaves<br />Reading a “list” of tasks<br />Distribution of the tasks to the slaves<br />Slave responsible for :<br />Execution of the task<br />Return execution status to the master<br />Key characteristics :<br />Slave death detection<br />Handle unhandled exceptions(+ hook)<br />Master &lt;-&gt; slave protocol allows temporary error code<br />Timeout of the tasks<br />
  39. 39. Step 4 : Some LibsMaster / Slave<br />One neat characteristic :<br />System might got bug in prod w/ minimal impact<br />If unhandled exception occurs<br />Only one slave dies<br />It is detected and master will fork a new one (if needed)<br />The lib handles the exception :<br />Default behavior : prints to console<br />User defined (callback) : e.g. write the stack trace to a file!<br />Cherry on the cake : getting specific production data about faulty task<br />
  40. 40. from robustpools.process_pool import master_task_list<br />from robustpools.process_pool import slave_task_list<br />m_config = { &apos;INFINITE_LOOP&apos; : 0 }<br />class list_task(object):<br /> def __init__(self, list, num, timeout_validity=600):<br />self.__num = num<br /> def _id(self):<br /> return self.__num<br /> id = property(_id) <br />class list_slave(slave_task_list):<br /> def __init__(self):<br />super(list_slave, self).__init__(list_task)<br /> def run(self, task):<br /> print task.id<br /> return 0, &quot;ok”<br />list = xrange(10)<br />m = master_task_list(list, num_slave=5, slave_class=list_slave, config=m_config)<br />m.start()<br />
  41. 41. Step 4 : Some LibsTCP Sockets Pool<br />Manage connections to a pool of servers<br />send in a round-robin/priority way to each server<br />Detect connection errors<br />Retry to connect<br />Number of retries limited =&gt; after mark as dead<br />Retry again later with exponential backoff<br />
  42. 42. Step 5 : Prove It Works<br />
  43. 43. Step 5 : Prove It Works<br />Prove = collect data … How?<br />Write integrated systems using bindings and libs of previous steps.<br />Show it works <br />Performance<br />Productivity<br />
  44. 44. Step 5 : Prove It Works<br />Performance, one obvious thought : C/C++<br />PINCS<br />Performance is not C, Stupid!<br />
  45. 45. Step 5 : Prove It WorksPerformance<br />Some of the rewrites works faster than C/C++ cousins<br />Why?<br />OS / Systems limits<br />Libs (legacy)<br />Algorithms<br />Software Architecture<br />Infrastructure<br />
  46. 46. Step 5 : Prove It WorksProductivity<br />BTW, pure performance so important?<br />Time to Market much more important<br />Adopt Lean Thinking and eliminate every possible waste<br /><ul><li>Writing too much code is a big waste in several ways</li></ul>Loose time when writing<br />Increase # bugs<br />More time to maintain<br />More time to know code base (think to new employees)<br /><ul><li>Impact Overall Productivity</li></li></ul><li>Step 5 : Prove It WorksProductivity<br />http://page.mi.fu-berlin.de/prechelt/Biblio/jccpprt2_advances2003.pdf<br />
  47. 47. Step 5 : Prove It WorksProductivity<br />http://page.mi.fu-berlin.de/prechelt/Biblio/jccpprt2_advances2003.pdf<br />
  48. 48. Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
  49. 49. Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
  50. 50. Step 5 : Prove It WorksProductivity<br />http://www.ohloh.net<br />
  51. 51. Step 5 : Prove It WorksProductivity<br />
  52. 52. Step 5 : Prove It WorksProductivity<br />Some existing C/C++ systems re-written in Python<br />Original C/C++ versions total of ~20.000 LOC <br />In Python, 4-6x less code !<br />The previous numbers do not seem to lie <br />
  53. 53. Step 5 : Prove It WorksProductivity<br />Oh, parsing an email?<br />Any idea in C/C++?<br />
  54. 54. Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email</li></ul>from email import message_from_file<br />fh = open(filename, “r”)<br />mail = message_from_file(fh)<br />fh.close()<br />
  55. 55. Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email</li></ul>content types of parts?<br />Any idea in C/C++ ?<br />from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, “r”)<br />mail = message_from_file(fh)<br />fh.close()<br />return mail<br />mail = get_mail(filename)<br />
  56. 56. Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
  57. 57. content types of parts</li></ul>from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, “r”)<br />mail = message_from_file(fh)<br />fh.close()<br />return mail<br />mail = get_mail(filename)<br />for part in mail.walk():<br /> print part.get_content_type()<br />
  58. 58. Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
  59. 59. content types of parts
  60. 60. getting headers?
  61. 61. Any idea in C/C++?</li></ul>from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, “r”)<br />mail = message_from_file(fh)<br />fh.close()<br />return mail<br />mail = get_mail(filename)<br />for part in mail.walk():<br /> print part.get_content_type()<br />
  62. 62. Step 5 : Prove It WorksProductivity<br /><ul><li>parsing an email
  63. 63. content types of parts
  64. 64. getting headers
  65. 65. Python libs are just that simple!</li></ul>… and there are a lot!<br />from email import message_from_file<br />def get_mail(filename):<br />fh = open(filename, “r”)<br />mail = message_from_file(fh)<br />fh.close()<br />return mail<br />mail = get_mail(filename)<br />for part in mail.walk():<br /> print part.get_content_type()<br />print mail[“From”]<br />print mail[“Subject”]<br />
  66. 66. Step 5 : Prove It WorksPerformance (Again?)<br />For equivalent architecture <br />(libs, algorithm, infrastructure)<br />C is a best performer than Python! <br />Python Is Not C, Stupid!<br />
  67. 67. Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br />PINCS! : think first to architecture!<br />
  68. 68. Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!</li></ul>Ctypes/ Swig : python bindings<br />Write your bottleneck in C / C++, use it in your python app<br />
  69. 69. Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!
  70. 70. Ctypes : absurdly easy python bindings</li></ul>Cython: write python, obtain a gcc compiled lib<br />
  71. 71. Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!
  72. 72. Ctypes : absurdly easy python bindings
  73. 73. Cython: write python, obtain a gcc compiled lib</li></ul>Psyco: JIT for python<br />Just an additional module import in your code<br />2 – 100x times faster than normal Python<br />Requires a bit more memory<br />
  74. 74. Step 5 : Prove It WorksPerformance (Again?)<br />Bottleneck discovered!<br /><ul><li>PINCS! : think first to architecture!
  75. 75. Ctypes : absurdly easy python bindings
  76. 76. Cython: write python, obtain a gcc compiled lib
  77. 77. Psyco: JIT for python
  78. 78. Unladden Swallow : Google Project
  79. 79. Produce a version of Python at least 5x faster
  80. 80. Every patch goes to Python (no fork!)</li></li></ul><li>Step 6 : Evangelize<br />
  81. 81. Step 6 : Evangelize<br />Once having stopped and look at what have been accomplished …<br />Show it, Evangelize!<br />
  82. 82. Step 6 : Evangelize<br />Because introducing a “new technology” is not just about teaching something to users. <br />You’ve got to play the role of evangelist! <br />Innovators (3.5%)<br />New stuffs? they’re in!<br />
  83. 83. Step 6 : Evangelize<br />Because introducing a “new technology” is not just about teaching something to users. <br />You’ve got to play the role of evangelist! <br /><ul><li>Innovators (3.5%) </li></ul>Early-adopters (12.5%)<br />Open to new ideas but check before<br />
  84. 84. Step 6 : Evangelize<br />Because introducing a “new technology” is not just about teaching something to users. <br />You’ve got to play the role of evangelist! <br /><ul><li>Innovators (3.5%)
  85. 85. Early-adopters (12.5%)</li></ul>Early majority (35%)<br />First, they must see the idea working<br />
  86. 86. Step 6 : Evangelize<br />Because introducing a “new technology” is not just about teaching something to users. <br />You’ve got to play the role of evangelist! <br /><ul><li>Innovators (3.5%)
  87. 87. Early-adopters (12.5%)
  88. 88. Early majority (35%)</li></ul>Late majority (35%)<br />Accept after lot of pressure, or imposed <br />
  89. 89. Step 6 : Evangelize<br />Because introducing a “new technology” is not just about teaching something to users. <br />You’ve got to play the role of evangelist! <br /><ul><li>Innovators (3.5%)
  90. 90. Early-adopters (12.5%)
  91. 91. Early majority (35%)
  92. 92. Late majority (35%)</li></ul>Laggard (14%)<br />Never accept (why would I want to change?) <br />
  93. 93. Step 6 : Evangelize<br />During work, I constantly spoke (a lot) to others<br />Presentation on Python made for all<br />Present to a large audience what has been done<br />Open discussion<br />Poster resuming what has been done<br />Wiki page documenting Python stuffs<br />Specific mailing-list related to Python<br />
  94. 94. Step 6 : Evangelize<br />lot of work and slow process but I won some allies<br />Some technical people are convinced that Python is useful<br />Some managers are convinced that Python could be a good thing for Terra <br />Starting evaluation in some specific cases<br />
  95. 95. Step 7 : Next Steps <br />
  96. 96. Step 7 : Next Steps <br />Proven that Python could be useful in some cases.<br />Don’t forget my Grail!<br />The way has not ended …<br />I’m lobbying to start using Python for web development.<br />And again, I made a prototype<br />
  97. 97. Step 7 : Next Steps <br />Django = THE Python MVC web framework :<br />Model :<br />By describing data, no code written (SQLAlchemy)<br />Automatic creation of tables (if needed),<br />Data accessed through objects,<br />No SQL needed!<br />View :<br />access models to get the data<br />render the output through templates<br /><ul><li>loose coupling interface <-> code!</li></ul>Controller :<br />REST through url parsing<br />
  98. 98. Step 7 : Next Steps <br />Login : <br />Module auth already exists.<br />Easy to tell django that authentication is required<br />@login_required<br />def list_abook(request, username):<br />…<br />login_requiredis a python decorator<br />
  99. 99. Step 7 : Next Steps <br />Caching information (memcache, bd, file, …)<br />4 levels :<br />Per site : one config line<br />Per view : one python decorator<br />@cache_page(60 * 15)<br />def list_abook(request, username):<br />…<br />In templates : maybe better to let this one out! <br />Low-level cache access :<br />cache.get(id)<br />cache.set(id, value, timeout) <br />
  100. 100. Step 7 : Next Steps <br />Address book Web Service<br />Retrieve address book of one user,<br />Add an account,<br />Add an entry to the address book of a user,<br />View all the address book entries,<br />Output in HTML, JSON and CSV<br />&lt; 100 LOC<br />2 hours (w/o knowing the framework)<br />Not one line of SQL<br />just usefulcode<br />
  101. 101. Conclusions<br />One year and a half …<br />and Evangelization is not done yet!<br />Email Team :<br />Several systems have been written in Python and works really fine … even with the Terra high load!<br />Web project should start right now<br />People are starting using/learning it inside the company<br />Some teams are starting evaluating Python<br />Some Terra employees here at this conference!<br />
  102. 102. THANKS!<br />Any Questions?<br />

×