Показаны сообщения с ярлыком students. Показать все сообщения
Показаны сообщения с ярлыком students. Показать все сообщения

пятница, 7 августа 2020 г.

How to handle a programming problem


A couple students whom I mentor through a software development course recently asked me for a generic advice on a way to approach a relatively large software development - something that would help them know where and how to start producing a solution. The question definitely provoked several pretty deep discussions. Since I do expect other students to seek advice of a similar kind I decided to devote a bit more time to the framing my advice.

While contemplating and discussing the topic I came up with a number of points that depict the approach that I use to build software. Sometimes I would follow this process to the point, in other cases I just adhere to the general line of thinking that it suggests - it definitely depends on the kind and size of a particular project. Thus, even though I present the approach as a sequence of steps, it is most reasonable to treat it as a description of a way of thinking about a programming problem.

Note that it so happened that I faced the question soon after going back to the Code Complete book to check a couple chapters. Moreover, I was reading How to Solve It by George Polya roughly at the same time. Because both of these have a lot to do with the topic at hand, the post definitely builds on the ideas found there. I absolutely recommend both of these books in case you didn't give these a try yet.

So, you find yourself with the task of producing a piece of software that would solve a particular issue. What should you do?
  1. First and foremost, state your problem in writing - what are you trying to solve?
  2. What requirements should the solution satisfy? Jot every one of these down as well.
  3. Imagine the final solution, state in writing what the thing that you are about to build will look like. Focus on the general shape of the final result here. See how it will solve the problem and meet the requirements.
  4. Think over the data model. Decide what kinds of data you will be handling, how to structure it better, where it comes from and where it should go. Imagine how the information is split into tables and collections, spot the relations between them. Consider which bits you need to store and how. Do this even if you don't have any kind of database - maybe building only a frontend application - data is something that you work with in any software and it definitely plays a great role in shaping the solution. Write all of this down.
  5. Decompose your future system or program based on what you have understood so far - think over how you can split the problem and the solution into pieces. Depending on the scale of the task you may be thinking on the level of services, modules or classes and functions here. The larger the problem - the larger should be the size of units considered on this design stage.
  6. In this process follow the breadth-first approach - e.g. don't go into designing functions before you produce an overview on the level of modules. List the large-scale units first, state their purpose clearly and only once this is done permit yourself to descend to the next level of detail. Notice when your start jumping between different levels of design - like thinking of modules, then functions, then modules again. If this happens stop and pull yourself back to the highest level that still needs clarifying.
  7. Don't overdesign and keep moving. Most of the technical design will happen while you're coding. Your key goal at the moment is to draw yourself a clear image of the whole solution, its components and relations that govern them and to see how you will meet every bit of requirements. Design can consume infinite time, so don't let yourself get lost in it - details will come.
  8. After facing your components think over your past experience - each component poses a smaller problem to solve and many of these smaller problems you may have solved in the past. If so, check which bits of previous projects you can use now - this may mean anything from pulling in a dozen existing files to just reviewing how you approached a particular issue a couple months ago.
  9. Throughout all these stages use pencil, draw figures, sketch stuff, write things down - it helps you think. Once you have started producing a diagram, your mind will follow. Draw how the system or its particular component is decomposed, outline relations between the pieces, sketch the data flow, chart user actions sequence.
  10. Devise a plan. Decide in which order you will build your components. Write that down (in any form or medium) - that will help you see and maintain progress, especially with longer projects
  11. Pick the first component on the list. Jot down the steps to build it. Think how to test it, list the functions to implement, decide on the order, add checkboxes. If you don't know how to pick the starting point, pick any single one of them. At this stage it’s most important just to start the job, so start anywhere. Even if you choose a wrong initial task, you will soon be able to see and correct that.
  12. Go and start writing the code. The first lines may go hard, but with all the preparatory work you should be able to break through them and the rest will follow easily.
  13. Don't try to write perfect code from scratch - start dirty. Starting is a challenge by itself, so simplify the task and relax the requirements. It is much easier to produce a dirty solution and clean it once you see it working. Just don't forget to always clean the mess.
  14. Write tests as you go to stay confident in the state of your code. Confidence does matter a lot here and the lack of it may slow you down significantly.
  15. Iterate. Pick small tasks, complete them, polish the solution, celebrate, step back to take a look at your design and plan, repeat.
  16. When you face challenges and are not sure where to go from there, take a pencil and think. State the problem that you're trying to solve, write out the required characteristics of the solution, draw, see it and then implement it.
  17. Yes, look for what others have to say about your problem - stackoverflow, github and google are your friends. Don’t just grab any code that you find on the web though - take time to understand what it does, why it works and what kind of new issues it may throw at you.
  18. When all else fails, go away for some time - take a walk, wash the dishes, smoke a pipe, use your hammock time. Let your brain wander away. Most times you will come back with new ideas. In the worst case you will get some rest and have more energy to continue attacking the problem.
And finally, if there are no more tasks to do, everything is polished and you feel happy about the result, celebrate the success, reward yourself, think over the lessons to learn from this project and go look for the next issue to solve. If you can program, there is an infinite number of problems waiting for you!

пятница, 7 февраля 2014 г.

Learning: MOOCs

I first attempted to do MOOCs when the whole thing started with Andrew Ng’s ‘Machine Learning’ and Sebastian Thrun’s ‘Introduction to AI’ back in 2011. For sure, both the ‘Machine Learning’ that I chose to take then and the courses, which followed, impacted my life significantly not only allowing me to explore loads of interesting stuff, but also enhancing my study at the university and to some extent forming the scope of my interests. This made me think a lot about the new phenomena of MOOCs and how they fit into our life and the world of education.

пятница, 20 июля 2012 г.

Learning to Program

About a year ago I took part in a vivid discussion of the best choice of the first programming language to study. The discussion didn't lead to any consensus thus making me think a lot about the question itself as well as remember the path along which I moved through the land of the programming craft.

вторник, 19 июня 2012 г.

A Justification for Excellent Marks


Being a fifth year student these days I am experiencing my tenth set of exams in university (oh, that's an anniversary!) As some students do I become tired and nervous when a semester draws to a close and consequently to exams - this particular semester is not an exception of any kind. These feelings usually are not caused by intensive studying during the term - instead these tend to be produced by insufficient studying. Moreover the lack of confidence is intensified by the simple fact that your knowledge and skills are to be condensed into a set of raw numbers or other symbols - your marks. 

I suppose that such state of affairs feels familiar to many students and I believe that some of them have faced an idea that the marks are frequently irrelevant as well. Saying 'irrelevant' I mean that marks do not reflect the level of student's knowledge and skills - the notion is evident considering the fact that generally it is too difficult to accurately assess the person's skills as well as knowledge by the means of a single examination and, besides that, such an assessment - even if it is accurate enough - can be much harder to map to the domain of numbers or symbols like A and D - the appearence of marks doesn't matter. This idea looks as obvious as safe, although some of it's derivatives turn out to be dangerous - it is very easy to decide not to perform any active preparation for exams if one believes that marks don't bear any meaning. Really, what can make you fight for treasures if you know these cost hardly anything?

Another problem that I see discouraging students from active studying in the end of a semester is seeming futility of some courses. It strikes hardly in most Russian universities where curriculum is fixed - that is the speciality you choose when enrolling or after the first year of study determines to the extent of 90% the set of courses which you will study. Such a system somehow simplifies student's life, but it also has significant drawbacks  - one of these is the possible and rather common failure to assure students that they actually need to study some particular discipline. This hardly helps students' training - particularly it fails to make them actively and properly study for exams. These arguments against preparation for exams may sound sensible - nevertheles I will try to partially overcome at least one of them - namely the idea that marks don't reflect the things they are supposed to reflect. 

Let us put the question "Should we actively prepare for exams?" aside for a moment and try to understand why don't marks reflect the level of student's knowledge. As I have said it may be rather difficult to evalueate the level of knowledge via an examination. These difficulties are generally caused by the nature of examinations - I mean the examinations that usually face. Commonly the person who tests you tries to evaluate your skills by analyzing your response to his or her questions. Moreover, examiner usually pays attention not only to the correctness of your answers but also to their completness as well as to your behaviour. Answering questions correctly and completely may require remembering a lot of things while making a proper impression on examiner is possible if you feel - or, at least, look - confident. I've already mentioned the possibility of significant problems with confidence during exams. As for remembering lots of details relevant to any particular course, I truly believe that such a thing is not of any importance if we speak of education and skills obtained through it. Moreover, the more we move towards the age of higly available learning and reference materials (or are we already there?) - the less inportant becomes one's ability to remember numerous low-level details. Here is a simple example: some programming language tutors (not very good ones usually) do prompt students to remember various very-low-level syntax features of the language being learnt, while from my point of view it is much more important to explain students the overall capabilities of the language and the key paradigms it is based upon. At the same time remebering low-level stuff seems to me not important - it will be developed through writing many programs - not through learning the things by heart. This idea becomes quite vivid when we speak of a language with complex syntax - say C++. I don't actually remember all the low-level details of this particular language, but it doesn't prevent me from writing programs in it because I usually need hardly a couple minutes to consult language reference available online about any particular detail that I need to use. Such an example of examiner's requirements may seem exaggerated but I do occasionally face something like this and encounters of this kind don't encourage me to study harder for exams - in fact these don't motivate to anything good at all.

From the other side the requirement to remember huge amount of non-important details is frequently delusive. The reason for this is that right-minded and experienced examiners usually ask questions that do not require all the irrelevant things like remembering low-level details - instead they know the questions that allow them to more or less accurately assess whether or not a particular student understands and feels the subject. So their questions prompt students just to combine good reasoning with their conceptual knowledge of the course subject. I aknowledge the fact that not all examiners behave like this, but I do hope that most teachers that one faces during his or her study do have preoper objectives and therefore perform examinations in a good way.

It turns out that thinking of your examiners as of the good ones is quite a good and helpful attitude because, besides the fact that it is the right way to think of other people, it also helps you switch the process of preparation for exams from attempts to memorize lots of facts to the study intended to develop deep understanding of the key concepts, problems, techniques and other high-level stuff that is truly relevant to the subject. However, even in case you believe that the person who performs examination is a dumb monster requiring only absolutely irrelevant things from you, the situation is not as bad as it may seem from the first glance. Firstly, it is common to have wrong impression about the examiner and secondly, even if you are not mistaken, the preapration for exam won't do any harm to you (except for consuming your energy, of course) - instead it will still help you dive deeply into the matter of the course and hopefully get out of there possessing really good understanding of the stuff. In fact, if one meets the need to memorize lots of details, one will firstly try to understand the forces that produce these details and the connections between them - that is, unwilling to remember many irrelevant things, one's mind will attempt to understand the relevant ones.

So the intensive preparation for exams seems to be worthwhile. That's why, while I still consider marks non-reflective of one's knowledge and skills, after posting this entry I am going to get back to studying for my next examination. To be honest, I should note that, despite my beliefs, I am still quite eager to get good ones - sometimes the contradiction feels confusing. However, there are at least two obvious ways to make marks meaningful: either do nothing, or study hard.