21
CS503: Seventeenth Lecture, Fall 2008 Problem Solving Michael Barnathan

CS503: Seventeenth Lecture, Fall 2008 Problem Solving Michael Barnathan

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

CS503: Seventeenth Lecture, Fall 2008

Problem SolvingMichael Barnathan

Here’s what we’ll be learning:• Theory:

– How to go from problems to code.– Problem solving as an art.– Mastery of your environment.

The Art of Computer Programming• Your degree ends with the phrase “of Science”, but problem solving is

very much an art.• Programming, therefore, is a bit of both art and science.• Art:

– Few hard, fast rules.– Some rules are unwritten.– Lots of room for creativity.– Improvement primarily through practice.

• Science:– Usually well-structured.– Well-defined methods (including the “scientific method”).– Improvement through practice and acquisition of knowledge.

• Because the rules are well-defined, knowing them helps.– Still lots of room for creativity.

• You can often “bend the rules”.

What is Computer Programming?• Actually writing the code is a very small part of being a

successful programmer.– 70% of it is figuring out how to break a problem down into

small, solvable, unambiguous pieces.– 20% is knowing what your tools are and how to use them

(languages, IDEs, debuggers…)– The other 10% is finding and using existing solutions so you’re

not reinventing the wheel.• Knowing the language is a necessary condition to be a

programmer at all, however!• Put it this way: does being fluent in English automatically

make you a good writer?– Of course not. But could you be a writer without knowing a

language? No; the language is your medium.

Your Tools• What trips most beginning CS students up is not an inability to solve

problems. It’s an inability to master their development environments.• You should know how to use, for each platform you develop on, at least:

– The language you’re coding in, obviously.– 1 IDE.– 2 widely available command-line editors (have the labs convinced you why

this is important yet?)– 1 compiler.– 1 debugger.– 1 UML/modeling program (Visio, ArgoUML, Dia, the Eclipse UML plugin, the

Netbeans UML plugin, Umbrello, …)• http://en.wikipedia.org/wiki/List_of_UML_tools

– 1 profiling tool (such as gprof or valgrind – these programs can help you fix performance bottlenecks and memory leaks, among other problems).

– 1 testing suite, such as JUnit.– 1 versioning/source control system, such as CVS or SVN.

• Don’t rely on an IDE. It’s a useful tool, but may not always be available.

Learning New Languages.• Most programmers who understand one

language well can learn new languages very rapidly.– Right now, you could probably learn C# within a few

weeks if you wished.– It may take you a bit longer to learn, say, Prolog, but

probably no more than a month.• This is not accidental: the languages are related

and express similar concepts.• So what I am aiming to teach is not Java, per se,

but programming in general.

And Tools• Tools are the same way. Their authors make them more usable by copying

metaphors from other tools.• For example, Ctrl+O is a near-universal “open” shortcut. You could use it

anywhere.• F5, F7, or F9 will usually run your program.• F10, shift+F10, and F11 are usually used to step through a program in a

debugger.• Ctrl+C is a universal command to break execution of a program.

– (It’s also the shortcut for the “copy” command. Ctrl+X is cut and Ctrl+V is paste).

• Ctrl+Z can be used to undo in most programs, Ctrl+Y to redo.• The shortcuts you learn in one place will often be used again in another.

– Even across platforms.• This makes learning the tools far easier.

Command-Line Editors• Since you are developing in Linux, you should make an

effort to learn how to use either vim or emacs.– Both are extremely powerful yet lightweight command-line

editors, but not the easiest to use.– I developed every assignment for this course in vim.

• If you need something easier-to-use, try nano.• Reasons to prefer these to IDEs:

– IDEs are cumbersome: if the project is small, they can do more harm than good.

– IDEs aren’t always available: there’s no guarantee you’ll be allowed to install NetBeans on a system.

– IDEs are bulky and slow: they try to do everything, but this can slow them down and consume a lot of memory.

The Tao• To become one with the program, you must clear

your mind of all distractions.• In other words, stop hunting for menu

commands and start writing code!• To achieve the highly creative state known as

“flow”, you need to be completely focused on solving the problem and writing code. You’ll never reach it if you’re struggling with the editor.– This is the state where you churn out thousands of

lines of high-quality code per hour, keep going all day, and only realize you forgot to eat after stopping.

Debuggers• Java’s debugger is known as jdb.• It’s a command line debugger, but frontends exist (IDEs build them in).• When compiling a program for a debugger, pass the -g option to javac. This

embeds symbols describing your program’s variables in the compiled class file.• Simple commands:

– help (by far the most important)– run: Runs the currently loaded program.– stop: Sets a breakpoint. The debugger will interrupt execution to allow debugging when a

breakpoint is hit.• “stop at Test:24”: breaks at test.java, line 24.• “stop in Test.testmethod”: breaks when Test.testmethod is invoked.

– print: prints out a variable or method’s value.– step: steps through the program line-by-line.– cont: continues execution after a breakpoint is hit.– where: prints a stack trace.

• up: goes one frame up the system stack. (pops)• down: goes one frame down the system stack if not already at the bottom. (pushes)

– locals: lists all local variables in the current stack frame.– list: prints the source around the current location.

Version Control• Your own personal time machine.• Stores old versions of programs and lets you revert back to them at need.• Also great for collaboration or if you work on the same documents from

place to place.• Every time you make a revision, you can save, or “commit” it to a version

control repository.• You can later compare further changes to any old version you’ve ever

committed (“diff”) or revert your changes entirely by “updating” to an old version.

• If you move to another system with an old copy, you can “update” it to the newest committed revision as well.

• You can also “check out” the latest update on a new system at any time.• The most popular systems are Subversion (SVN) and CVS. Using one will

make your task far easier.

Existing Solutions• You have other sorts of tools, too. These don’t help you code; they

help you find code.– Google.– Koders.– Krugle.– PlanetSourceCode.– SourceForge.– CPAN (for Perl) and other module repositories.– Many others…

• Use these when you hit roadblocks: chances are that others have hit them too, and their solutions can help you.

• Also use them to find libraries; try not to waste time doing something that has already been done.– Being able to quickly understand and use these libraries from their

documentation is an essential programming skill as well.

What’s the Connection?

• What lets me take metaphors from one language or UI and simply assume they will work in others?

• Why can some people use programs they had never seen before, while others have difficulty with tasks they haven’t memorized?

Intuition.

Intuitive Design• Good UIs are intuitive.

– They place tasks where users expect to find them (e.g. “Open” is always under the “File” menu because it’s the first place people will look).

– They utilize the same sorts of shortcuts as other programs.– Commands are placed according to their function; common functionalities are

grouped.– Frequently used commands should be easy to access.

• Good languages are intuitive.– They do what you’d expect them to, and only what you’d expect them to.– Command names hint at their functionality.– Nothing is “magic”; commands don’t mean different things in different places.

• Good programs are intuitive.– Variable and function names represent their functions.– There is a sense of overall structure to the program.– The pieces are split up in a self-contained way, like a puzzle fitting together.– It is clear what role each piece plays in solving the problem.– Nothing is done “by accident” – every piece of the program serves a purpose.

Problem Solving• An art: there are no strict rules.• There are some recurring patterns, though.• Takes both intelligence and creativity.

– Most people don’t realize it at first, but computer science is a very creative field.• The algorithm design paradigms are problem solving strategies:

– Divide and Conquer: break the problem down into smaller instances of itself, solve them, and merge them back together.

– Memoization: store solutions to smaller problems and look them up when needed.– The Greedy Approach: solve the problem by making the best short-term decision at each step.– Dynamic Programming: build the solution up from overlapping smaller solutions.

• Also some others we didn’t discuss:– Hill Climbing: come up with an approximate solution, then gradually improve it.– Genetic Algorithms: generate many solutions, have them compete, and select the best ones.

• Solutions are often easier to verify than to generate, so this can work well.• Visualization of the problem can help you solve it.

– Flowcharts, UML, graphs, diagrams… sometimes the key is to just get an image of what the solution must do into your head.

• Intuition is important here too: go beyond the verbal description of the problem and try to understand what the problem actually is.

Solutions• Only once you understand the problem can you

begin working on a solution to it.• In programming, the solution usually involves an

“architecture”: some hierarchy of self-contained components which interact to generate a solution.

• Algorithms are recipes for solving problems, so think of the architecture as a way of enabling you to do complex things like “create a pizza crust”, rather than having to list out each step involved in creating a crust at once.

Problem: Make a Pizza

• Questions to ask:– What is a pizza?• A pielike food with a crust on the bottom, topped with

cheese and tomato sauce.– What “high-level” ingredients will be required?• Crust.• Sauce.• Cheese.

– How can they interact to create a pizza?• The crust can be rolled thin, the sauce spread on top of

it, and the cheese added, in that order. The assembled pizza is then baked in a pizza oven for 10 to 15 minutes.

Drill-Down• What is involved in generating the crust, sauce,

and cheese?– Crust: flour, wheat, water, … must be mixed to

generate a dough.– Sauce: either created by mashing tomatoes or simply

bought ready-made (libraries!)– Cheese: needs to be shredded before topping on a

pizza.• Note that we don’t care about rolling the dough,

adding the sauce, or adding the cheese at this level. We’ve dealt with that above.

“Pseudocode”• Once we’ve drilled down to an elementary level, we are ready to construct a

solution from our architecture:Pizza makepizza() {

//Gather low-level ingredients.Tomato[] tomatoes = new Tomato[5];Flour fl = Cabinet.getBagOfFlour();Cheese ch = new Mozzarella(); //Polymorphism. Mozzarella “ISA” Cheese.Water w = Sink.pour(4); //Pour 4 ounces of water.

Crust cr = Crust.mix(fl, w);Sauce s = Tomato.mash(tomatoes);Pizza p = new Pizza(cr, s, ch);Oven.bake(p, 350, 15);

return p;}

Now With a Program

• Say you wanted to create a booking system for an airline.– What components would your program need?– How would they interact?– What low-level operations might each component

need to perform?– What data must be stored by each?

I have problems.

• This lesson was on problem solving and problem decomposition, as well as mastery of your development environment.

• Specifically, it covered how to solve problems using the programming techniques you have been learning in this course and elsewhere.

• The lesson:– Problem solving is often a matter of intuition, in

which both intelligence and creativity are brought to bear.