Related
I'm a very experienced developer - done a lot of heavy duty work with Delphi, C# and C++ for years. I have always adhered very closely to the guidelines for structured programming, OOP, loosely coupled modular designs etc - and since all the languages I've used have built-in ways of enforcing these concepts - access control, static types, interface and abstract class support etc - I rely on these to structure my code.
Now, I have been doodling with Python for a few months. I am impressed by its many wonderful features - but I sorely miss the built-in constraints that make it easy to keep code modularized and organized. And, unfortunately, I see an awful lot of 'spaghetti code' out there written in Python, even from very respectable sources. I won't single anyone out but I have a few books written by major league pythonistas with examples replete with designs (better put - 'anti-designs') that make me shudder. It seems to me that because Python is so easy to use, it's also very easy to abuse.
I do try to discipline myself when I code in Python, but I find it takes a lot of extra work to implement and often I have to set up and adhere to constraints simply based on my own memory of the design with no help from the language at all. And since there is no 'compile time' checking, it's doubly difficult - often you don't discover a design flaw until you actually RUN that segment of code.
So, I'm looking for very specific information: some examples or better still a book of WELL STRUCTURED Python designs and design techniques - how to best implement encapsulation, indirection, very loosely coupled designs, etc.
Bad design IMO from a prominent python book author - (with obfuscation)
def populateList(self, selecteddisk=None):
selected = None ***#Bundling - coupling:***
self.listWidget.clear()
for disk in self.disks.inOrder():
item = QListWidgetItem(QString("%1 of %2/%3 (%L4)") \
.arg(disk.name).arg(disk.owner).arg(disk.country) \
.arg(disk.teu))
self.listWidget.addItem(item)
***#Bundling - coupling:***
if selecteddisk is not None and selecteddisk == id(disk):
selected = item
if selected is not None:
selected.setSelected(True)
self.listWidget.setCurrentItem(selected)
I find it takes a lot of extra work to implement and compile code that adheres to constraints simply based on my own memory of the design with no help from the language when writing the code itself before compiling. Some IDE's offer help, but the language itself offers me no help at all.
And since 'compile time' checking never seems to help me find ordinary logic bugs it's doubly difficult - often you don't discover a design flaw until you actually RUN that segment of code.
Python designs and design techniques ...
how to best implement encapsulation,
By encapsulating. In languages like Java and C++, "encapsulation" has grown to mean "uses private stuff all over the place." In Python that's simply not supported.
We're All Adults Here.
You still do encapsulation just like you did in every other language. Without the word private, however.
Python offers properties, decorators and overrides to __getattribute__ to implement various kinds of encapsulation techniques.
indirection,
By referencing other objects. I'm not clear on what specific problems you have here, but perhaps you've passed some wrong-type argument to a function. The way to avoid this is to read the docstrings you wrote for yourself.
very loosely coupled designs, etc.
By doing dependency injection. Again. Python works just like every other language with respect to loose coupling.
You should investigate -- and use -- docstrings heavily.
You might want to use https://www.sphinx-doc.org to generate nice documentation from your docstrings.
You can also use Python's built-in help() function to read the docstrings you wrote when you wrote your code.
On design pattern support:
There is a proposition that also puts that Design Patterns as a crude metric of gaps in a programming language. It would be an interesting read and counterpoint to your suggestion that design patterns are constraints supported by language.
http://www.oscon.com/oscon2008/public/schedule/detail/2810
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've been learning, working, and playing with Python for a year and a half now. As a biologist slowly making the turn to bio-informatics, this language has been at the very core of all the major contributions I have made in the lab. I more or less fell in love with the way Python permits me to express beautiful solutions and also with the semantics of the language that allows such a natural flow from thoughts to workable code.
What I would like to know is your answer to a kind of question I have seldom seen in this or other forums. This question seems central to me for anyone on the path to Python improvement but who wonders what his next steps should be.
Let me sum up what I do NOT want to ask first ;)
I don't want to know how to QUICKLY learn Python
Nor do I want to find out the best way to get acquainted with the language
Finally, I don't want to know a 'one trick that does it all' approach.
What I do want to know your opinion about, is:
What are the steps YOU would recommend to a Python journeyman, from apprenticeship to guru status (feel free to stop wherever your expertise dictates it), in order that one IMPROVES CONSTANTLY, becoming a better and better Python coder, one step at a time. Some of the people on SO almost seem worthy of worship for their Python prowess, please enlighten us :)
The kind of answers I would enjoy (but feel free to surprise the readership :P ), is formatted more or less like this:
Read this (eg: python tutorial), pay attention to that kind of details
Code for so manytime/problems/lines of code
Then, read this (eg: this or that book), but this time, pay attention to this
Tackle a few real-life problems
Then, proceed to reading Y.
Be sure to grasp these concepts
Code for X time
Come back to such and such basics or move further to...
(you get the point :)
I really care about knowing your opinion on what exactly one should pay attention to, at various stages, in order to progress CONSTANTLY (with due efforts, of course). If you come from a specific field of expertise, discuss the path you see as appropriate in this field.
EDIT: Thanks to your great input, I'm back on the Python improvement track! I really appreciate!
I thought the process of Python mastery went something like:
Discover list comprehensions
Discover generators
Incorporate map, reduce, filter, iter, range, xrange often into your code
Discover Decorators
Write recursive functions, a lot
Discover itertools and functools
Read Real World Haskell (read free online)
Rewrite all your old Python code with tons of higher order functions, recursion, and whatnot.
Annoy your cubicle mates every time they present you with a Python class. Claim it could be "better" implemented as a dictionary plus some functions. Embrace functional programming.
Rediscover the Strategy pattern and then all those things from imperative code you tried so hard to forget after Haskell.
Find a balance.
One good way to further your Python knowledge is to dig into the source code of the libraries, platforms, and frameworks you use already.
For example if you're building a site on Django, many questions that might stump you can be answered by looking at how Django implements the feature in question.
This way you'll continue to pick up new idioms, coding styles, and Python tricks. (Some will be good and some will be bad.)
And when you see something Pythony that you don't understand in the source, hop over to the #python IRC channel and you'll find plenty of "language lawyers" happy to explain.
An accumulation of these little clarifications over years leads to a much deeper understanding of the language and all of its ins and outs.
Understand (more deeply) Python's data types and their roles with regards to memory mgmt
As some of you in the community are aware, I teach Python courses, the most popular ones being the comprehensive Intro+Intermediate course as well as an "advanced" course which introduces a variety of areas of application development.
Quite often, I get asked a question quite similar to, "Should I take your intro or advanced course? I've already been programming Python for 1-2 years, and I think the intro one is too simple for me so I'd like to jump straight to the advanced... which course would you recommend?"
To answer their question, I probe to see how strong they are in this area -- not that it's really the best way to measure whether they're ready for any advanced course, but to see how well their basic knowledge is of Python's objects and memory model, which is a cause of many Python bugs written by those who are not only beginners but those who have gone beyond that.
To do this, I point them at this simple 2-part quiz question:
Many times, they are able to get the output, but the why is more difficult and much more important of an response... I would weigh the output as 20% of the answer while the "why" gets 80% credit. If they can't get the why, regardless how Python experience they have, I will always steer people to the comprehensive intro+intermediate course because I spend one lecture on objects and memory management to the point where you should be able to answer with the output and the why with sufficient confidence. (Just because you know Python's syntax after 1-2 years doesn't make you ready to move beyond a "beginner" label until you have a much better understanding as far as how Python works under the covers.)
A succeeding inquiry requiring a similar answer is even tougher, e.g.,
Example 3
x = ['foo', [1,2,3], 10.4]
y = list(x) # or x[:]
y[0] = 'fooooooo'
y[1][0] = 4
print x
print y
The next topics I recommend are to understanding reference counting well, learning what "interning" means (but not necessarily using it), learning about shallow and deep copies (as in Example 3 above), and finally, the interrelationships between the various types and constructs in the language, i.e. lists vs. tuples, dicts vs. sets, list comprehensions vs. generator expressions, iterators vs. generators, etc.; however all those other suggestions are another post for another time. Hope this helps in the meantime! :-)
ps. I agree with the other responses for getting more intimate with introspection as well as studying other projects' source code and add a strong "+1" to both suggestions!
pps. Great question BTW. I wish I was smart enough in the beginning to have asked something like this, but that was a long time ago, and now I'm trying to help others with my many years of full-time Python programming!!
Check out Peter Norvig's essay on becoming a master programmer in 10 years: http://norvig.com/21-days.html. I'd wager it holds true for any language.
Understand Introspection
write a dir() equivalent
write a type() equivalent
figure out how to "monkey-patch"
use the dis module to see how various language constructs work
Doing these things will
give you some good theoretical knowledge about how python is implemented
give you some good practical experience in lower-level programming
give you a good intuitive feel for python data structures
def apprentice():
read(diveintopython)
experiment(interpreter)
read(python_tutorial)
experiment(interpreter, modules/files)
watch(pycon)
def master():
refer(python-essential-reference)
refer(PEPs/language reference)
experiment()
read(good_python_code) # Eg. twisted, other libraries
write(basic_library) # reinvent wheel and compare to existing wheels
if have_interesting_ideas:
give_talk(pycon)
def guru():
pass # Not qualified to comment. Fix the GIL perhaps?
I'll give you the simplest and most effective piece of advice I think anybody could give you: code.
You can only be better at using a language (which implies understanding it) by coding. You have to actively enjoy coding, be inspired, ask questions, and find answers by yourself.
Got a an hour to spare? Write code that will reverse a string, and find out the most optimum solution. A free evening? Why not try some web-scraping. Read other peoples code. See how they do things. Ask yourself what you would do.
When I'm bored at my computer, I open my IDE and code-storm. I jot down ideas that sound interesting, and challenging. An URL shortener? Sure, I can do that. Oh, I learnt how to convert numbers from one base to another as a side effect!
This is valid whatever your skill level. You never stop learning. By actively coding in your spare time you will, with little additional effort, come to understand the language, and ultimately, become a guru. You will build up knowledge and reusable code and memorise idioms.
If you're in and using python for science (which it seems you are) part of that will be learning and understanding scientific libraries, for me these would be
numpy
scipy
matplotlib
mayavi/mlab
chaco
Cython
knowing how to use the right libraries and vectorize your code is essential for scientific computing.
I wanted to add that, handling large numeric datasets in common pythonic ways(object oriented approaches, lists, iterators) can be extremely inefficient. In scientific computing, it can be necessary to structure your code in ways that differ drastically from how most conventional python coders approach data.
Google just recently released an online Python class ("class" as in "a course of study").
http://code.google.com/edu/languages/google-python-class/
I know this doesn't answer your full question, but I think it's a great place to start!
Download Twisted and look at the source code. They employ some pretty advanced techniques.
Thoroughly Understand All Data Types and Structures
For every type and structure, write a series of demo programs that exercise every aspect of the type or data structure. If you do this, it might be worthwhile to blog notes on each one... it might be useful to lots of people!
I learned python first by myself over a summer just by doing the tutorial on the python site (sadly, I don't seem to be able to find that anymore, so I can't post a link).
Later, python was taught to me in one of my first year courses at university. In the summer that followed, I practiced with PythonChallenge and with problems from Google Code Jam.
Solving these problems help from an algorithmic perspective as well as from the perspective of learning what Python can do as well as how to manipulate it to get the fullest out of python.
For similar reasons, I have heard that code golf works as well, but i have never tried it for myself.
Learning algorithms/maths/file IO/Pythonic optimisation
This won't get you guru-hood but to start out, try working through the Project Euler problems
The first 50 or so shouldn't tax you if you have decent high-school mathematics and know how to Google. When you solve one you get into the forum where you can look through other people's solutions which will teach you even more. Be decent though and don't post up your solutions as the idea is to encourage people to work it out for themselves.
Forcing yourself to work in Python will be unforgiving if you use brute-force algorithms.
This will teach you how to lay out large datasets in memory and access them efficiently with the fast language features such as dictionaries.
From doing this myself I learnt:
File IO
Algorithms and techniques such as Dynamic Programming
Python data layout
Dictionaries/hashmaps
Lists
Tuples
Various combinations thereof, e.g. dictionaries to lists of tuples
Generators
Recursive functions
Developing Python libraries
Filesystem layout
Reloading them during an interpreter session
And also very importantly
When to give up and use C or C++!
All of this should be relevant to Bioinformatics
Admittedly I didn't learn about the OOP features of Python from that experience.
Have you seen the book "Bioinformatics Programming using Python"? Looks like you're an exact member of its focus group.
You already have a lot of reading material, but if you can handle more, I recommend you
learn about the evolution of python by reading the Python Enhancement Proposals, especially the "Finished" PEPs and the "Deferred, Abandoned, Withdrawn, and Rejected" PEPs.
By seeing how the language has changed, the decisions that were made and their rationales, you will absorb the philosophy of Python and understand how "idiomatic Python" comes about.
http://www.python.org/dev/peps/
Attempt http://challenge.greplin.com/ using Python
Teaching to someone else who is starting to learn Python is always a great way to get your ideas clear and sometimes, I usually get a lot of neat questions from students that have me to re-think conceptual things about Python.
Not precisely what you're asking for, but I think it's good advice.
Learn another language, doesn't matter too much which. Each language has it's own ideas and conventions that you can learn from. Learn about the differences in the languages and more importantly why they're different. Try a purely functional language like Haskell and see some of the benefits (and challenges) of functions free of side-effects. See how you can apply some of the things you learn from other languages to Python.
I recommend starting with something that forces you to explore the expressive power of the syntax. Python allows many different ways of writing the same functionality, but there is often a single most elegant and fastest approach. If you're used to the idioms of other languages, you might never otherwise find or accept these better ways. I spent a weekend trudging through the first 20 or so Project Euler problems and made a simple webapp with Django on Google App Engine. This will only take you from apprentice to novice, maybe, but you can then continue to making somewhat more advanced webapps and solve more advanced Project Euler problems. After a few months I went back and solved the first 20 PE problems from scratch in an hour instead of a weekend.
I'm currently reading a great book called 'Programming Collective Intelligence' by Toby Segaran (which i highly recommend)
The code examples are all written in Python, and as I have already learnt one new language this year (graduating from VB.net to C#) i'm not keen to jump on another learning curve.
This leaves my with the issue of translating the python examples into C#.
Question is: How critical is it that the code stay in python? Are there thing in python that I can't do in a normal managed statically typed language?
One challenge you'll find is that not only are the algorithms implemented in Python, but the book makes extensive use of Python libraries like BeautifulSoup, Numpy, PIL, and others (see appendix A).
I doubt there are any specifics of the algorithms that you couldn't port to another language, but you'll have trouble working through the exercises. Also, to translate the code, you'll have to learn Python at least a little bit, no?
I suggest you just dive in and learn Python. You can use IronPython if you have any concern about interoperability with your C# projects.
You can do the same things in all Turing-complete languages. Here is an example for rendering a Mandelbrot fractal in SQL. The example shows: Even if you can use any language, the effort will be different.
So my guess is that the code will become much longer since Python is so flexible and open.
I suggest translating them to C#. I have been porting chapter 2 "Recommendations" to VB.Net. Along the way I'm learning Python as a side-effect. Toby does some amazing things with Python lists.
Dealing with the the extra Python libraries is another story. Ndelicious is a close match to pyDelicious, but it is missing a few key features (popular posts!).
Obligatory XKCD: http://xkcd.com/353/
I know you explicitly say you don't want to learn Python (this year), but translating the Python examples to C# will definitely be a much steeper curve. Just dive in!
The book is about algorithms, not the details of programming, and the language of choice is just to make the examples concrete. As the author says, "The code examples in this book are written in Python... but I provide explanations of all the algorithms so that programmers of other languages can follow." (p. xv)
Python is a great language and easy to learn, but I suspect the difficulties in applying ideas from the book will not be in the translating of the code to another language or set of libraries, but in understanding the ideas and modifying the code to suite your needs. I think there are two main reasons to stay with a language you're familiar with: 1) when your code doesn't work, if you're writing in an unfamiliar language, you won't know where to start looking for errors, e.g. if you're like most people you'll even start wondering if it's due to a bug in Python, which it won't be, but you'll wonder and it will distract. 2) There are just natural limits to how much you can remember in a certain length of time; and learning a language at the same time will give you twice as much to remember.
It depends though how well you know C#, and what you lose by leaving it.
Python seems to be to AI programming what LISP was for for many decades. Russel/Norvig's famous book AI: A Modern Approach also provides lots of examples in Python.
I am currently in the process of making an embedded system port of the CPython 3.0 Python interpreter and I'm particularly interested in any references or documentation that provides details about the design and structure of code for Release 3.0 or even about any of the 2.x releases.
One useful document I have found so far is this informational PEP on the implementation - which is a good overview - but is still pretty high level. Hoping to come across something that gives [much] more detail on more of the modules or perhaps even covers something about porting considerations.
There's the documentation for the C API, which is essentially the API for the internals of Python. It won't cover porting details, though. The code itself is fairly well documented. You might try reading in and around the area you'll need to modify.
Most of the documentation is stored in the minds of various core developers. :) A good resource for you would be the #python-dev IRC channel on freenode where many of them hang out.
There's also some scattered information on the Python wiki.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
The first language I learnt was PHP, but I have more recently picked up Python. As these are all 'high-level' languages, I have found them a bit difficult to pick up. I also tried to learn Objective-C but I gave up.
So, what language should I learn to bridge between Python to C
It's not clear why you need a bridge language. Why don't you start working with C directly? C is a very simple language itself. I think that hardest part for C learner is pointers and everything else related to memory management. Also C lang is oriented on structured programming, so you will need to learn how to implement data structures and algorithms without OOP goodness. Actually, your question is pretty hard, usually people go from low level langs to high level and I can understand frustration of those who goes in other direction.
The best place to start learning C is the book "The C Programming Language" by Kernighan and Ritchie.
You will recognise a lot of things from PHP, and you will be surprised how much PHP (and Perl, Python etc) do for you.
Oh and you also will need a C compiler, but i guess you knew that.
I generally agree with most of the others - There's not really a good stepping stone language.
It is, however, useful to understand what is difficult about learning C, which might help you understand what's making it difficult for you.
I'd say the things that would prove difficult in C for someone coming from PHP would be :
Pointers and memory management This is pretty much the reason you're learning C I imagine, so there's not really any getting around it. Learning lower level assembly type languages might make this easier, but C is probably a bridge to do that, not the other way around.
Lack of built in data structures PHP and co all have native String types, and useful things like hash tables built in, which is not the case in C. In C, a String is just an array of characters, which means you'll need to do a lot more work, or look seriously at libraries which add the features you're used to.
Lack of built in libraries Languages like PHP nowadays almost always come with stacks of libraries for things like database connections, image manipulation and stacks of other things. In C, this is not the case other than a very thin standard library which revolves mostly around file reading, writing and basic string manipulation. There are almost always good choices available to fill these needs, but you need to include them yourself.
Suitability for high level tasks If you try to implement the same type of application in C as you might in PHP, you'll find it very slow going. Generating a web page, for example, isn't really something plain C is suited for, so if you're trying to do that, you'll find it very slow going.
Preprocessor and compilation Most languages these days don't have a preprocessor, and if you're coming from PHP, the compilation cycle will seem painful. Both of these are performance trade offs in a way - Scripting languages make the trade off in terms of developer efficiency, where as C prefers performance.
I'm sure there are more that aren't springing to mind for me right now. The moral of the story is that trying to understand what you're finding difficult in C may help you proceed. If you're trying to generate web pages with it, try doing something lower level. If you're missing hash tables, try writing your own, or find a library. If you're struggling with pointers, stick with it :)
Learning any language takes time, I always ensure I have a measurable goal; I set myself an objective, then start learning the language to achieve this objective, as opposed to trying to learn every nook and cranny of the language and syntax.
C is not easy, pointers can be hard to comprehend if you’re not coming assembler roots. I first learned C++, then retro fit C to my repertoire but I started with x86 and 68000 assembler.
Python is about as close to C as you're going to get. It is in fact a very thin wrapper around C in a lot of places. However, C does require that you know a little more about how the computer works on a low level. Thus, you may benefit from trying an assembly language.
LC-3 is a simple assembly language with a simulated machine.
Alternatively, you could try playing with an interactive C interpreter like CINT.
Finally, toughing it out and reading K&R's book is usually the best approach.
Forget Java - it is not going to bring you anywhere closer to C (you have allready proved that you don't have a problem learning new syntax).
Either read K&R or go one lower: Learn about the machine itself. The only tricky part in C is pointers and memory management (which is closely related to pointers, but also has a bit to do with how functions are called). Learning a (simple, maybe even "fake" assembly) language should help you out here.
Then, start reading up on the standard library provided by C. It will be your daily bread and butter.
Oh: another tip! If you really do want to bridge, try FORTH. It helped me get into pointers. Also, using the win32 api from Visual Basic 6.0 can teach you some stuff about pointers ;)
C is a bridge onto itself.
K&R is the only programming language book you can read in one sitting and almost never pick it up again ...
My suggestion is to get a good C-book that is relevant to what you want to do. I agree that K & R is considered to be "The book" on C, but I found "UNIX Systems Programming" by Kay A. Robbins and Steven Robbins to be more practical and hands on. The book is full of clean and short code snippets you can type in, compile and try in just a few minutes each.
There is a preview at http://books.google.com/books?id=tdsZHyH9bQEC&printsec=frontcover (Hyperlinking it didn't work.)
I'm feeling your pain, I also learned PHP first and I'm trying to learn C++, it's not easy, and I am really struggling, It's been 2 years since I started on c++ and Still the extent of what I can do is cout, cin, and math.
If anyone reads this and wonders where to start, START LOWER.
Java might actually be a good option here, believe it or not. It is strongly based on C/C++, so if you can get the syntax and the strong typing, picking up C might be easier. The benefit is you can learn the lower level syntax without having to learn pointers (since memory is managed for you just like in Python and PHP). You will, however, learn a similar concept... references (or objects in general).
Also, it is strongly Object Oriented, so it may be difficult to pick up on that if you haven't dealt with OOP yet.... you might be better off just digging in with C like others suggested, but it is an option.
I think C++ is a good "bridge" to C. I learned C++ first at University, and since it's based on C you'll learn a lot of the same concepts - perhaps most notably pointers - but also Object Oriented Design. OO can be applied to all kinds of modern languages, so it's worth learning.
After learning C++, I found it wasn't too hard to pick up the differences between C++ and C as required (for example, when working on devices that didn't support C++).
try to learn a language which you are comfortable with, try different approach and the basics.
Languages are easy to learn (especially one like C)... the hard part is learning the libraries and/or coding style of the language. For instance, I know C++ fairly well, but most C/C++ code I see confuses me because the naming conventions are so different from what I work with on a daily basis.
Anyway, I guess what I'm trying to say is don't worry too much about the syntax, focus on said language's library. This isn't specific to C, you can say the same about c#, vb.net, java and just about every other language out there.
Pascal! Close enough syntax, still requires you to do some memory management, but not as rough for beginners.