AlphaGo Improving Itself - algorithm

I've read a couple news articles about AlphaGo and they all mention that AlphaGo became better from first playing human games, then playing games against itself. One thing I am curious about is, how did AlphaGo improve itself? Does it modify variables in the code? Or does it change it's code completely writing it itself? Or did the creators add it? How does it actually learn? A generalised answer is fine as it's just for my general knowledge.
Maybe I'm misunderstanding the whole concept, news articles tend to give a broad and sometimes misinformed understanding. Some clarity would be great or links to useful information.

AlphaGo uses machine learning.
In Machine Learning you have a function (say ax +b) that gives you a result and you tune the parameters of that function (a and b) so that the result matches more and more the examples you have. In the case of AlphaGo they had 2 functions, one to pick the next move and and one to say who is winning, and both are very complex with many thousands of parameters.
When they played a game between two instances of AlphaGo they would record the result and use it as an example to train the functions, so that the next version plays even better.
There are great tutorials on the web on how machine learning works if you want to know more.

Related

What's the most effective workflow between people who develop algorithms and developers?

We are developing software with pattern recognition in video. We have 7 mathematicians who are creating algorithms. Plus we have 2 developers that maintain / develop the application with these algorithms. The problem is that mathematicians are using different development tools to create algorithm like Matlab, C, C++. Also because they are not developers the don't give much concerns for memory management or multi-threading. This one of the reason why the app. has a lot of bugs.
If in your company you have similar situation, how do you deal with it? What's the best tools you can recommend to create algorithms? What communication supposed to be between mathematicians and developers? What's in your opinion the most effective to work with high-level tools?
I am not sure whether you devs are rewriting the mathematician's stuff or if you just have to interface to it so I am not sure if my answer is of any use.
However: I work together with a bunch of phd candidates and postdocs on a machine learning library and am a student myself. In that process, I came to translate a lot of algorithms from python/numpy to C++/blas.
This process can be quite tedious - especially with numerical and stochastic algorithms, it is hard to find bugs.
So here is what I did: Get some sample inputs and calculate the results with the python code. Generate unit tests out of these for C++ and then start coding them in C++.
Checking concrete sample inputs with the outputs is essential in this setting.
I agree with Makach.
Let the guys who are creating the algorithms use the tools that they are most familiar with. Because there are two separate (and equally important) tasks to work on in this project. First, there is the creating of an efficient, elegant and appropriate mathematically sound algorithm, then there is the twistedly difficult task of translating it into CPU-speak. The mathimaticians should focus on their first task, and to make it easier for them, allow them to use the toosl they are comfortable with. In terms of man hours, it is a much more efficient use of their time to write MATLAB code, than it would be to have them learn a new programming language.
Your task is to unearth the (presumably) brilliant mathematics that are buried within the gibberish code.
That part is just a perspective on the problem at hand. Here's the actual answer.
Communication, mutual respect, and teaching/learning.
Communication & Mutual Respect
You must communicate with them often. Work closely with them and ask them questions whenever you come across something you're not sure of. This is much easier when there is mutual respect, which means that if you spend all your time criticizing their coding abilities, then they will be forced to spend all their time criticizing your math abilities. Instead, try quick learning-sessions. ("Lunch & Learn" is a fairly common tactic)
Teaching/Learning
The first and most important piece of wisdom to impart to them is commenting. Have them comment the crap out of their code. Tell them that the comments are much more important than the code quality, and that as long as their comments are right, they can leave the rest up to you guys. Because they can. They don't need to have their code look beautiful, for be the fastest, they just need it to make sense to you guys.
To continue this mutual learning scenario, if you notice some very simple very common mistakes they are making, (nothing NEARLY as complicated as multithreading) just give them a quick heads up. "That way works (or doesn't) but here's a way to do it that is a little different but it will make your lives much much easier." Encourage them to reciprocate by trying to notice which nuances or parts of their algorithms which you and your team are having difficulty with and teach a little tutorial about it.
Once you guys get the communication flowing, you'll find it easier and easier to shape their coding style to what is best for your team, and they will also find it easier to understand why you don't see it the same way they do.
Also, as mentioned by Kekoav, make sure they provide a few fully loaded test cases.
That means for something like
A -> B -> C -> D -> Solution
They would provide you all the values for A, then what it looks like at B, then what it looks like at C and so on. So that you can be certain that not only is it correct at the end, but it's also correct at every step of the way. Try to have them provide examples that are regular, and also a few of them that are unusual, so that you can be certain your code covers edge cases.
I'd recommend the devs spend a few hours getting used to Matlab, especially the Matlab debugger. If their background is CS then they'll already be familiar with vectors and matrices theoretically if not practically. Other than the matrix being the default data structure, Matlab is C-like and easy enough to interpret for translation into another language.
I have been working with a physics professor lately, and have a little experience with this(although admittedly I'm no expert).
I have had to translate a lot of Matlab code into another language. It has been difficult because a lot of(most) of the operations are absent, including when it comes to precision, and working with matrices and vectors. A good math library needs to be found, or created to fit your needs.
The best way that I have found is to do the following:
Get the algorithm to work correctly in the new language.
Create some tests to verify that the algorithm is producing desired output. Have your mathematicians verify that your converted solution in fact works, and that you have covered all bases with your tests.
Then after it is working, and you can trust your tests, optimize the algorithm to be good coding style, have good design and performance characteristics. Use your regression tests to make sure you aren't breaking anything.
I normally start with a verbatim copy of their algorithms into the other language, and then work from there, regardless of if I do a lot of tests.
It is important to get a working copy first, in case the performance is really not an issue and you need to move on to other things and can come back later to make it faster.
This is your job. How you deal with this is what identifies you as a system developer.
Communicate with your colleagues. Draw and explain, have meetings, agree upon and set standards requirements, follow your plans and talk to your project manager. Make sure that your relevant colleagues are joining up on meetings. Have 1-1 talks etc etc
You cannot blame it on the mathematicians for developers creating bugs. It's their job to worry about implementation, not the mathematicians.

What learning habits can you suggest? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Our profession often requires deep learning; sitting down and reading, and understanding. I'm currently undergoing an exam period, and I'm looking for ways to learn more effectively.
I'm not asking about what to learn, or whether to prefer blogs over books, etc. My question is much more physical than that -
What do you do when need to study, and I mean study hard?
I'm looking for answers such as
I slice my time to 2.5 hours intervals and make a break between them, but never during.
I keep a jar of water nearby.
I wake up at 6 o'clock sharp and start my day with a session at the gym.
What good learning habits did acquire, or wish you had acquired?
(I know this isn't strictly programming related, but it is programmers related)
I find the best way to set yourself up for learning is:
Get plenty of exercise and rest
Eat a balanced diet with little sugar and caffeine
Try to find a quiet area conducive to concentration
Try to practice what you learn from a book - theory is ok, but practice embeds the knowledge.
"The best way to test whether or not you know something is to try to explain it to someone else from scratch."
That has to be one of the best ideas I was ever given about knowing whether or not I really know something.
Make sure it's quiet and comfortable around you.
enough to drink and eat
don't just read but take notes, draw mindmaps and the like
don't just read but try
make a report, blog entry, presentation out of what you learned
learn the same thing from different sources: Don't just believe what person A has to say look for, read and understand the opinion of person B and C as well and understand the differences.
take nothing for granted
apply the knowledge to an actual project
I set aside time every day or x times per week. Otherwise I never do it.
I try to have a diff location every once and awhile (home / coffee shop / stay late at the office) keeps the tedium away.
I am careful about the music I use, try to make sure it is relaxing
Sometimes I leave headphones on even if music is off that way people don't talk to me.
I give myself specific goals before each break or for every session.
I reward myself
Read Andy Hunt's "Pragmatic Thinking and Learning" - lots of good suggestions there.
Tony Buzan wrote The Mind Map Book, describing his ideas for note taking. He also has some process ideas that I found very helpful. Foremost was this one: study new material for an hour, then take a short break (5-10 minutes) and then review the new material. Review the new material again an hour later, then two hours after that, then the next day. You need to refresh your exposure to the material multiple times over the course of time to really take it in.
While reading, I make sure I fully comprehend each section in the text before I continue.
Set up a time and take away all distractions. At home/dorm can be rough, so I would use the library while in college. Getting started is usually the hardest part, so don't set a specific time limit for when to quit. It is distracting, and you will be looking at your clock to see "how much longer you have." You don't want to be in that mindset. Work until you feel your brain is starting to lose focus, whether that is lack of comprehension or having to reread simple paragraphs repeatedly. Take a minute or two as a break, then refocus your mind. When that stops working, it is time for a real break.
Are you a night owl or early bird? Each person is different. I am very productive early in the morning, while my wife can barely function. We all have differences, so don't try to fight your nature.
+1 to what everyone else said. Making cheat sheet/notes were a very important part of my studying habits, whether I could use them on the exam or not.
I find it best to be fully dedicated to the task before I start. If you go into something with low morale, you will not do well. If you go into a task with high morale, you will understand things quicker, be able to apply it to real situations better, and will have a deeper comprehension. If I am not fully dedicated, I don't even bother. I've got better things to do with my time then half ass something, and you probably do too.
Expanding on a comment I left, see this article from Electronic Design from a few years ago: http://electronicdesign.com/Articles/Index.cfm?AD=1&ArticleID=5859.
If you can teach what you learned, you know it.
by Louis Frenzel
All learning is self-learning. Professors, trainers, and all teachers just organize and present the material to be learned. They don't teach it to you. You learn it. You're the one who actually absorbs, understands, and assimilates the knowledge by listening to the lectures, reading, thinking, solving problems, and other activities. Self-learning is a natural, human quality. While most of you have used this method in the past, you may want to do it on a more formal basis to speed up and fine-tune your methods. Here's a suggested approach (and trust me on this, you must write it down):
Clearly identify what you want to learn. Write it out.
Write some learning objectives for yourself. These statements clearly identify what you want to know and be able to do. For example, you should write something like "When I complete this learning assignment, I will be able to design and program an FIR DSP filter." The objectives should be expressed in "behavioral" terms, that is, using words that state some measurable outcome.
Identify some initial resources. Start with books at the local bookstore or go to www.Amazon.com or Barnes & Noble at www.barnesandnoble.com. Most cities don't have good technical bookstores, and it's tough to find anything at regular bookstores. Consider yourself lucky if you have a good technical bookstore or a good college bookstore. Plan to get multiple books to give you greater breadth of coverage with multiple explanations, examples, and perspectives. Don't forget to look through your stack of magazine back issues.
Check out online sources. Do one or more Web searches, or go to relevant company Web sites. You may run across an appropriate tutorial, white paper, or application note that will give you what you need. The large semiconductor and equipment manufacturers have tons of stuff on their Web sites, so start digging. Also check out the professional societies and other sources listed in the tables and sidebars.
Watch out for any conferences or seminars on this topic. Usually, such events never occur when you need them, but you might get lucky. If you find one, attend because it will provide a big head start for your own learning.
Organize your materials. Lay them out, mark them up, and then make an outline based on your objectives. See what you have and what you lack, and make an initial list of things to do.
Dig in. Set aside an hour a day or whatever you can to go through the materials. Turn off the radio, CD player, and television. Make a habit of finding some quiet time to read and learn.
Look for a human tutor. You could be working just down the hall from an expert on the very subject you're trying to learn. Pick his or her brain. Ask this person if he/she will help you understand and learn. Take this person to lunch or offer to pay for lessons. Most people will gladly share what they know, if you aren't too proud to ask. The best way to do this is to learn as much as you can on your own. Then, go for the professional, personal help with tough questions or when you get stuck.
Include some hands-on. Is there any hardware you can buy or put together to help you learn it? Maybe there's some software that will help. Buy it or have your employer buy it.
Write a paper or article or teach what you have learned. You have to know it to write it or teach it. There's no better way to learn for yourself than to have to explain it to others.
I generally find it useful to build a "cheat sheet" or other form of summary as I go.
On one hand, it forces me to reinterpret information and figure out what's really important.
On the other hand, I'm building a useful study tool for last-minute revisions, or future refreshing of knowledge.
2.5 hours without breaks seems like a lot. Experiment with different time slots to see what works best (personally, a sequence of 3x(20 work - 5 break) works well)
Pomodoro Technique for time management
http://pomodorotechnique.com/get-started/
(watch "how" tab)
And the code(for programmers)
while(day) {
for (int i = 0; i < 4; i++) {
work(25);
relax(i < 3 ? 5 : 15);
}
}
You should implement methods
void work(int minutes);
void relax(int minutes);
Variable day changes from other threads

Minimum CompSci Knowledge Needed for Writing Desktop Apps

Having been a hobbyist programmer for 3 years (mainly Python and C) and never having written an application longer than 500 lines of code, I find myself faced with two choices :
(1) Learn the essentials of data structures and algorithm design so I can become a l33t computer scientist.
(2) Learn Qt, which would help me build projects I have been itching to build for a long time.
For learning (1), everyone seems to recommend reading CLRS. Unfortunately, reading CLRS would take me at least an year of study (or more, I'm not Peter Krumins). I also understand that to accomplish any moderately complex task using (2), I will need to understand at least the fundamentals of (1), which brings me to my question : assuming I use C++ as the programming language of choice, which parts of CLRS would give me sufficient knowledge of algorithms and data structures to work on large projects using (2)?
In other words, I need a list of theoretical CompSci topics absolutely essential for everyday application programming tasks. Also, I want to use CLRS as a handy reference, so I don't want to skip any material critical to understanding the later sections of the book.
Don't get me wrong here. Discrete math and the theoretical underpinnings of CompSci have been on my "TODO: URGENT" list for about 6 months now, but I just don't have enough time owing to college work. After a long time, I have 15 days off to do whatever the hell I like, and I want to spend these 15 days building applications I really want to build rather than sitting at my desk, pen and paper in hand, trying to write down the solution to a textbook problem.
(BTW, a less-math-more-code resource on algorithms will be highly appreciated. I'm just out of high school and my math is not at the level it should be.)
Thanks :)
This could be considered heresy, but the vast majority of application code does not require much understanding of algorithms and data structures. Most languages provide libraries which contain collection classes, searching and sorting algorithms, etc. You generally don't need to understand the theory behind how these work, just use them!
However, if you've never written anything longer than 500 lines, then there are a lot of things you DO need to learn, such as how to write your application's code so that it's flexible, maintainable, etc.
For a less-math, more code resource on algorithms than CLRS, check out Algorithms in a Nutshell. If you're going to be writing desktop applications, I don't consider CLRS to be required reading. If you're using C++ I think Sedgewick is a more appropriate choice.
Try some online comp sci courses. Berkeley has some, as does MIT. Software engineering radio is a great podcast also.
See these questions as well:
What are some good computer science resources for a blind programmer?
https://stackoverflow.com/questions/360542/plumber-programmers-vs-computer-scientists#360554
Heed the wisdom of Don and just do it. Can you define the features that you want your application to have? Can you break those features down into smaller tasks? Can you organize the code produced by those tasks into a coherent structure?
Of course you can. Identify any 'risky' areas (areas that you do not understand, e.g. something that requires more math than you know, or special algorithms you would have to research) and either find another solution, prototype a solution, or come back to SO and ask specific questions.
Moving from 500 loc to a real (eve if small) application it's not that easy.
As Don was pointing out, you'll need to learn a lot of things about code (flexibility, reuse, etc), you need to learn some very basic of configuration management as well (visual source safe, svn?)
But the main issue is that you need a way to don't be overwhelmed by your functiononalities/code pair. That it's not easy. What I can suggest you is to put in place something to 'automatically' test your code (even in a very basic way) via some regression tests. Otherwise it's going to be hard.
As you can see I think it's no related at all to data structure, algorithms or whatever.
Good luck and let us know
I must say that sitting down with a dry old textbook and reading it through is not the way to learn how to do anything effectively, even if you are making notes. Doing it is the best way to learn, using the textbooks as a reference. Indeed, using sites like this as a reference.
As for data structures - learn which one is good for whatever situation you envision: Sets (sorted and unsorted), Lists (ArrayList, LinkedList), Maps (HashMap, TreeMap). Complexity of doing basic operations - adding, removing, searching, sorting, etc. That will help you to select an appropriate library data structure to use in your application.
And also make sure you're reasonably warm with MVC - i.e., ensure your model is separate from your view (the QT front-end) as best as possible. Best would be to have the model and algorithms working on their own, and then put the GUI on top. Or a unit test on top. Etc...
Good luck!
It's like saying you want to move to France, so should you learn french from a book, and what are the essential words - or should you just go to France and find out which words you need to know from experience and from copying the locals.
Writing code is part of learning computer science. I was writing code long before I'd even heard of the term, and lots of people were writing code before the term was invented.
Besides, you say you're itching to write certain applications. That can't be taught, so just go ahead and do it. Some things you only learn by doing.
(The theoretical foundations will just give you a deeper understanding of what you wind up doing anyway, which will mainly be copying other people's approaches. The only caveat is that in some cases the theoretical stuff will tell you what's futile to attempt - e.g. if one of your itches is to solve an NP complete problem, you probably won't succeed :-)
I would say the practical aspects of coding are more important. In particular, source control is vital if you don't use that already. I like bzr as an easy to set up and use system, though GUI support isn't as mature as it could be.
I'd then move on to one or both of the classics about the craft of coding, namely
The Pragmatic Programmer
Code Complete 2
You could also check out the list of recommended books on Stack Overflow.

Basic programming/algorithmic concepts [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm about to start (with fellow programmers) a programming & algorithms club in my high school. The language of choice is C++ - sorry about that, I can't change this. We can assume students have little to no experience in the aforementioned topics.
What do you think are the most basic concepts I should focus on?
I know that teaching something that's already obvious to me isn't an easy task. I realize that the very first meeting should be given an extreme attention - to not scare students away - hence I ask you.
Edit: I noticed that probably the main difference between programmers and beginners is "programmer's way of thinking" - I mean, conceptualizing problems as, you know, algorithms. I know it's just a matter of practice, but do you know any kind of exercises/concepts/things that could stimulate development in this area?
Make programming fun!
Possible things to talk about would be Programming Competitions that either your club could hold itself or it could enter in locally. I compete in programming competitions at the University (ACM) level and I know for a fact that they have them at lower levels as well.
Those kind of events can really draw out some competitive spirit and bring the club members closer.
Things don't always have to be about programming either. Perhaps suggest having a LAN party where you play games, discuss programming, etc could be a good idea as well.
In terms of actual topics to go over that are programming/algorithm related, I would suggest as a group attempting some of these programming problems in this programming competition primer "Programming Challenges": Amazon Link
They start out with fairly basic programming problems and slowly progress into problems that require various Data Structures like:
Stacks
Queues
Dictionaries
Trees
Etc
Most of the problems are given in C++.
Eventually they progress into more advanced problems involving Graph Traversal and popular Graph algorithms (Dijkstra's, etc) , Combinatrics problems, etc. Each problem is fun and given in small "story" like format. Be warned though, some of these are very hard!
Edit:
Pizza and Soda never hurts either when it comes to getting people to show up for your club meetings. Our ACM club has pizza every meeting (once a month). Even though most of us would still show up it is a nice ice breaker. Especially for new clubs or members.
Breaking it Down
To me, what's unique about programming is the need to break down tasks into small enough steps for the computer. This varies by language, but the fact that you may have to write a "for loop" just to count to 100 takes getting used to.
The "top-down" approach may help with this concept. You start by creating a master function for your program, like filterItemsByCriteria();
You have no idea how that will work, so you break it down into further steps:
(Note: I don't know C++, so this is just a generic example)
filterItemsByCritera() {
makeCriteriaList();
lookAtItems();
removeNonMatchingItems();
}
Then you break each of those down further. Pretty soon you can define all the small steps it takes to make your criteria list, etc. When all of the little functions work, the big one will work.
It's kind of like the game kids play where they keep asking "why?" after everything you say, except you have to keep asking "how?"
Linked lists - a classic interview question, and for good reason.
I would try to work with a C subset, and not try to start with the OO stuff. That can be introduced after they understand some of the basics.
Greetings!
I think you are getting WAY ahead of yourself in forcing a specific language and working on specific topics and a curriculum.. It sounds like you (and some of the responders) are confusing "advising a programming club" with "leading a programming class". They are very different things.
I would get the group together, and the group should decide what exactly they want to get out of the club. In essence, make a "charter" for the club. Then (and only then) can you make determinations such as preferred language/platform, how often to meet, what will happen at the meetings, etc.
It may turn out that the best approach is a "survey", where different languages/platforms are explored. Or it may turn out that the best approach is a "topical"one, where there topic changes (like a book club) on a regular basis (this month is pointers, next month is sorting, the following is recursion, etc.) and then examples and discussions occur in various languages.
As an aside, I would consider a "language-agnostic" orientation for the club. Encourage the kids to explore different languages and platforms.
Good luck, and great work!
Well, it's a programming club, so it should be FUN! So I would say dive into some hand on experience right away. Start with explaining what a main() method is,then have students write a hello world program. Gradually improve the hello world program so it has functions and prints out user inputs.
I would say don't go into algorithm too fast for beginners, let them play with C++ first.
Someone mentioned above, "make programming fun". It is interesting today that people don't learn for the sake of learning. Most people want instant gratification.
Teach a bit of logic using Programming. This helps with(and is) problem solving. The classing one I have in my head are guessing games.
Have them make a program that guesses at a number between 0 and 100.
Have them make a black jack clone ... I have done this in basic :-(
Make paper instructions.
Explain the "Fried eggs" story. Ask the auditory what they would do to make themselves fried eggs. Make them note the step they think about. Probably you will receive less than 5 steps algorithm. Then explain them how many steps should be written down if we want to teach a computer to fry eggs. Something like:
1) Go to the Fridge
2) Open the fridge door
3) Search for eggs
4) If there are no eggs - go to the shop to buy eggs ( this is another function ;) )
5) If there are eggs - calculate how many do you need to fry
6) Close the fridge door
7) e.t.c. :)
Start with basics of C - syntax semantics e.t.c, and in parallel with that explain the very basic algorithms like bubble sort.
After the auditory is familiar with structured programming (this could take several weeks or months, depending how often you make the lessons), you can advance to C++ and OOP.
The content in Deitel&Deitel's C++ programming is a decent introduction, and the exercises proposed at the end of each chapter are nice toy problems.
Basically, you're talking about:
- control structures
- functions
- arrays
- pointers and strings
You might want to follow up with an introduction to the STL ("ok, now that we've done it the hard way... here's a simpler option")
Start out by making them understand a problem like for instance sorting. This is very basic and they should be able to relate quite fast. Once they see the problem then present them with the tools/solution to solve it.
I remember how it felt when I first was show an example of merge-sort. I could follow all the steps but what the hell was I for? Make then crave a solution to a problem and they will understand the tool and solution much better.
start out with a simple "hello world" program. This introduces fundamentals such as variables, writing to a stream and program flow.
Then add complexity from there (linked lists, file io, getting user input, etc).
The reason I say start with hello world is because the kid will get to see a running program really quick. It's nearly immediate feedback-as they will have written a running program right from the start.
IMO, Big-O is one of the more important concepts for beginning programmers to learn.
Have a debugging contest. Provide code samples that include a bug. Have a contest to see who can find the most or fastest.
There is an excellent book, How Not to Program in C++, that you could use to start with.
You always learn best from mistakes and I prefer to learn from some else's.
It will also let those with little experience learn by see code, even if the code only almost works.
In addition to the answers to this question, there are certain important topics to cover. Here's an example of how you could structure the lessons.
First Lesson: Terminology and Syntax
Terminology to cover: variable, operator, loop (iteration), method, reserved word, data type, class
Syntax to cover: assignment, operation, if/then/else, for loop, while loop, select, input/output
Second Lesson: Basic Algorithm Construction
Cover a few simple algorithms, involving some input, maybe a for or a while loop.
Third Lesson: More Advanced Algorithm Topics
This is for things like recursion, matrix manipulation, and higher-level mathematics. You don't have to get into too complex of topics, but introduce enough complexity to be useful in a real project.
Final Lesson: Group Project
Make a project that groups can get involved in doing.
These don't have to be single day lessons. You can spread the topics across multiple days.
Pseudocode should be a very first.
Edit: If they are total programming beginners then I would make the first half just about programming. Once you get to a level where talking about algorithms would make sense then pseudocode is really important to get under the nails.
Thanks for your replies!
And how would you teach them actual problem solving?
I know a bunch of students that know C++ syntax and a few basic algorithms, but they can't apply the knowledge they know when they solve real problems - they don't know the approach, the way to transcribe their thoughts into a set of strict steps. I do not talk about 'high-level' approaches like dynamic programming, greedy etc., but about basic algorithmic mindset.
I assume it's just because of the poor learning process they were going through. In other sciences - math, for example - they are really brilliant.
Just because you are familiar with algorithms does not mean you can implement them and just because you can program does not mean you can implement an algorithm.
Start simple with each topic (keep programming separate from designing algorithms). Once they have a handle on each, slowly start to bring the two concepts together.
Wow. C++ is one of the worst possible languages to start with, in terms of the amount of unrelated crap you need to get anything working (Java would be slightly worse, I guess).
When teaching beginners in a boilerplate-heavy environment, it's usual to start with "here's a simple C program. We'll discuss what all this crap at the top of the file is for later, but for now, concentrate on the lines between 'int main(void)' and the 'return' statement, which is where all the useful work is accomplished".
Once you're past that point, basic concepts to cover include the basic data structures (arrays, linked lists, trees, and dictionaries), and the basic algorithms (sorting, searching, etc).
Have your club learn how to actually program in any language by teaching the concepts of building software. Instead of running out an buying a dozen licenses for Visual Studio, have students use compilers, make systems, source files, objects and librarys in order to turn their C code into programs. I feel this is truly the beginning and actually empowers these kids to understand how to make software on any platform, without crutches that many educational institutions like to rely on.
As for the language of choice - congratulations - you'll find C++ is very rich in making you think of mathematical shortcuts and millions of ways to make your code perform even better (or to implement fancy patterns).
To the question: When I was beggining to program I would always try to break down one real life problem into several steps and then as I see similarity between tasks or data they transform I would always try to find a lazier, easier, meanier way to implement it.
Elegance came after when learning patterns and real algorithms.
Hank: Big O??? you mean tell beginning programmers that their code is of O(n^2) and yours is of n log n ??
I could see a few different ways to take this:
1) Basic programming building blocks. What are conditional statements, e.g. switch and if/else? What are repetition statements, e.g. for and while loops? How do we combine these to get a program to be the sequence of steps we want? You could take something as easy as adding up a grocery bill or converting temperatures or distances from metric to imperial or vice versa. What are basic variable types like a string, integer, or double? Also in here you could have Boolean Algebra for an advanced idea or possibly teach how to do arithmetic in base 2 or 16 which some people may find easy and others find hard.
2) Algorithmically what are similar building blocks. Sorting is a pretty simple topic that can be widely discussed and analysed to try to figure out how to make this faster than just swapping elements that seem out of order if you learn the Bubblesort which is the most brain dead way to do.
3) Compiling and run-time elements. What is a call stack? What is a heap? How is memory handled to run a program,e.g. the code pieces and data pieces? How do we open and manipulate files? What is compiling and linking? What are make files? Some of this is simple, but it can also be eye-opening just to see how things work which may be what the club covers most of the time.
These next 2 are somewhat more challenging but could be fun:
4) Discuss various ideas behind algorithms such as: 1) Divide and conquer, 2) Dynamic programming, 3) Brute force, 4) Creation of a data structure, 5) Reducing a problem to a similar one already solved for example Fibonacci numbers is a classic recursive problem to give beginning programmers, and 6) The idea of being, "greedy," like in a making change example if you were in a country where coin denominations where a,b, and c. You could also get into some graph theory examples like a minimum weight spanning tree if you want something somewhat exotic, or the travelling salesmen for something that can be easy to describe but a pain to solve.
5) Mathematical functions. How would you program a factorial, which is the product of all numbers from 1 to n? How would you compute the sums of various Arithmetic or Geometric Series? Or compute the number of Combinations or Permutations of r elements from a set of n? Given a set of points, approximate the polynomial that meets this requirement, e.g. in a 2-dimensional plane called x and y you could give 2 points and have people figure out what are the slope and y intercept if you have solved pairs of linear equations already.
6) Lists which can be implemented using linked lists and arrays. Which is better for various cases? How do you implement basic functions such as insert, delete, find, and sort?
7) Abstract Data Structures. What are stacks and queues? How do you build and test classes?
8) Pointers. This just leads to huge amounts of topics like how to allocate/de-allocate memory, what is a memory leak?
Those are my suggestions for various starting points. I think starting a discussion may lead to some interesting places if you can get a few people together that don't mind talking on the same subject week after week in some cases as sorting may be a huge topic to cover well if you want to get into the finer points of things.
You guys could build the TinyPIM project from "C++ Standard Library from Scratch" and then, when it's working, start designing your own extensions.

How do you prevent over complicated solutions or designs? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Many times we find ourselves working on a problem, only to figure out the solution being created is far more complex than the problem requires. Are there controls, best practices, techniques, etc that help you control over complication in your workplace?
Getting someone new to look at it.
In my experience, designing for an overly general case tends to breed too much complexity.
Engineering culture encourages designs that make fewer assumptions about the environment; this is usually a good thing, but some people take it too far. For example, it might be nice if your car design doesn't assume a specific gravitational pull, nobody is actually going to drive your car on the moon, and if they did, it wouldn't work, because there is no oxygen to make the fuel burn.
The difficult part is that the guy who is developed the "works-on-any-planet" design is often regarded as clever, so you may have to work harder to argue that his design is too clever.
Understanding trade-offs, so you can make the decision between good assumptions and bad assumptions, will go a long way into avoiding a needlessly complicated design.
If its too hard to test, your design is too complicated. That's the first metric I use.
Here are some ideas to get design more simpler:
read some programming books and articles, and then apply them in your work and write code
read lots of code (good and bad) written by other people (like Open Source projects) and learn to see what works and what does not
build safety nets (unit tests) to enable experimentations with your code
use version control to enable rollback, if those experimentations take wrong turn
TDD (test driven development) and BDD (behaviour driven development)
change your attitude, ask how you can make it so, that "it simply works" (convention over configuration could help there; or ask how Apple would do it)
practice (like jazz players -- jam with code, try Code Kata)
write same code multiple times, with different languages and after some time has passed
learn new languages with new concepts (if you use static language, learn dynamic one; if you use procedural language, learn functional one; ...) [one language per year is about right]
ask someone to review you code and actively ask how you can make your code simpler and more elegant (and then make it)
get years under your belt by doing above things (time helps active mind)
I create a design etc., and then I look at it and try and remove (agressively) everything that doesn't seem to be needed. If it turns out I need it later when I am polishing the design I add it back in. I do this over several iterations, refining as I go along.
Read "Working Effectively With Legacy Code" by Michael C. Feathers.
The point is, if you have code that works, and you need to change the design, nothing works better than making your code unit testable, and breaking your code into smaller pieces.
Using Test Driven Development and following Robert C. Martin's Three Rules of TDD:
You are not allowed to write any production code unless it is to make a failing unit test pass.
You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
In this way you are not likely to get much code that you don't need. You will always be focused on making one important thing work and won't ever get too far ahead of yourself in terms of complexity.
Test first may help here, but it is not suitable for all situation. And it's not a panacea anyway.
Start small is another great idea. Do you really need to stuff all 10 design patterns into this thing? Try first to do it "stupid way". Doesn't quite cut it? Okay, do it "slightly less stupid way". Etc.
Get it reviewed. As someone else wrote, two pairs of eyes are better. Even better are two brains. Your mate may just see a room for simplification, or a problematic area you thought was fine just because you spend many hours hacking it.
Use lean language. Languages such as Java, or sometimes C++ sometimes seem to encourage nasty, convoluted solutions. Simple things tend to span over multiple lines of code, and you just need to use 3 external libraries and a big framework to manage it all. Consider using Python, Ruby, etc. - if not for your project, then for some private use. It can change your mindset to favor simplicity, and to be assured that simplicity is possible.
Reduce the amount of data you're working with by serialising the task into a series of smaller tasks. Most people can only hold half a dozen (plus or minus) conditions in their head while coding, so make that the unit of implementation. Design for all the tasks you need to accomplish, but then ruthlessly hack the design so that you never have to play with more than half a dozen paths though the module.
This follows from Bendazo's post - simplify until it becomes easy.
It is inevitable once you have been a programmer that this will happen. If you seriously have unestimated the effort or hit a problem where your solution just doesn't work then stop coding and get talking to your project manager. I always like to take the solutions with me to the meeting, problem is A, you can do x which will take 3 days or we can try y which will take 6 days. Don't make the choice yourself.
Talk to other programmers every step of the way. The more eyes there are on the design, the more likely an overcomplicated aspect is revealed early, before it becomes too ossified in the codebase.
Constantly ask yourself how you will use whatever you are currently working on. If the answer is that you're not sure, stop to rethink what you're doing.
I've found it useful to jot down thoughts about how to potentially simplify something I'm currently working on. That way, once I actually have it working, it's easier to go back and refactor or redo as necessary instead of messing with something that's not even functional yet.
This is a delicate balancing act: on the one hand you don't want something that takes too long to design and implement, on the other hand you don't want a hack that isn't complicated enough to deal with next week's problem, or even worse requires rewriting to adapt.
A couple of techniques I find helpful:
If something seems more complex than you would like then never sit down to implement it as soon as you have finished thinking about it. Find something else to do for the rest of the day. Numerous times I end up thinking of a different solution to an early part of the problem that removes a lot of the complexity later on.
In a similar vein have someone else you can bounce ideas off. Make sure you can explain to them why the complexity is justified!
If you are adding complexity because you think it will be justified in the future then try to establish when in the future you will use it. If you can't (realistically) imagine needing the complexity for a year or three then it probably isn't justifiable to pay for it now.
I ask my customers why they need some feature. I try and get to the bottom of their request and identify the problem they are experiencing. This often lends itself to a simpler solution than I (or they) would think of.
Of course, if you know your clients' work habits and what problems they have to tackle, you can understand their problems much better from the get-go. And if you "know them" know them, then you understand their speech better. So, develop a close working relationship with your users. It's step zero of engineering.
Take time to name the concepts of the system well, and find names that are related, this makes the system more familiar. Don't be hesitant to rename concepts, the better the connection to the world you know, the better your brain can work with it.
Ask for opinions from people who get their kicks from clean, simple solutions.
Only implement concepts needed by the current project (a desire for future proofing or generic systems make your design bloated).

Resources