I just want to get some information before I go ask my teacher during his offices hours tomorrow.
We have have project to do thats something like an iclicker question answer collector. He told us to avoid using switch case statements. I was just wondering why and why don't people in the field like using them, what alternative is there to do? and I doubt he wants us to use if statements either.
I think we have to use polymorphism/interfaces but I just cant rap my head around that, switch cases seems so much straight forward.
Thank you.
Usually when an instructor asks "don't use feature X", it's because they want you to learn how to do something without using a feature that might be a shortcut. In your case, it sounds like your instructor wants you to wrap your head around polymorphism. If you don't, you won't learn that bit and will have much more trouble later in the class.
It depends upon the project. For example, in using a RESTful APi, you do have switch statements because there is a limit, known set. But, with your program there might be a lot of different options and that option can change, increase (or decrease), so while you started out with three cases, then something else is wanted, that's four, then five, and so on. You end up with 50 cases, and that's probably not good or easy to maintain.
With your OOP class, the instructor is probably going to show you that. Come back and show the whole problem and the final result, and maybe others can shed light.
There's an example that I've seen in my old Java book, and did a search and see it is still decent. Consider employees and salaries. You have three types of employees, then you have 50 types.
On a small scale, there appears to be not much difference. It requires enlarging the problem and considering consequences.
Ways to eliminate switch in code
That is a good example. Sure, there's only two cases in that example. But, again, what if it were 50? How easy will it be to maintain that? A lot of things in programming are about saving time and making things logical in the long run, as you will be coming back to your code or someone else's, and you have to maintain and support it.
Related
Some information (don't want to confuse you with a lot of shitty code):
I've done a pretty large console programm (my largest project so far) which helps me a lot with managing some accounts / assets and more. I'm constantly adding more features but at the same time I reshape the code to work on my shitty coding style.
The console program has a lot of commands the user can type and for every command different methods get called / objects get created / manipulated and so on.
My keywords which are saved in an ArrayList<String> and my commands have this type: [keyword] [...n more Strings]
DESIGN PROBLEM 1:
I have a method cmdProcessor(String[] arguments) which handles the input (command) of the user, and the [keyword] is always the first argument arguments[0]. That means I have a large number of if-statements of this type:
if(arguments[0].equalsIgnoreCase("keyword") callMethod(argmts); where in the String[] argmts the remaining arguments[1] ... [n] are.
Is this a good way to handle this or should I go with switch-case?
Or something else (what?)? Is it better to save the keywords in a HashMap<String, Method>?
DESIGN PROBLEM 2:
The methods (see above callMethod(argmts) ), which are triggered by the entered keyword look even more chaotic. Since the same method can have different numbers and forms of arguments saved in the String[] argmts the method is full of if(argmts.length == ...) to check length, and every of these if-blocks has a bunch of switch-case options which also have a lot of ifs and so on. The last else and the default-case in switch-case I always use for error-handling (throwing error codes and and explanation why the pattern doesn't match and so on).
Is this good or are there better ways?
I thought about using lots of submethods, which would also blow up
my program and cost a lot of time but maybe improve readability / overview. Is this okay, or what is the best
option in such cases (lots of ifs and switch-case)?
Since I want to build more and more around this program maybe I should start now to fix bad design before it's too late. :)
About Design-Problem 1:
My go-to would be to register a lot of Handlers, which you can base on a common interface and then implement the specific behavior individually. This is good, because the central method handling your input is slim, and you only need to register a lot of singletons once, on initialization. Disadvantage: if you forget one, it will not work. So maybe, you can register them automatically (reflection or something thelike).
Aside from that, a map is better than a List in this case, because (I assume) you don't need a sorting. You need a mapping from key to behavior, so a map seems better (though even a very large set of keywords would probably not be very inefficient, if you stick to a list).
About Design Problem 2:
If I was you, I'd use actual Regular-Expression patterns. Take a look at the java.util.regex.Pattern-class. You can isolate groups and validate the values you receive. Though it does not spare you the exception/error-handling, it does help a lot in segmentation and interpretation efforts.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I understand the JVM optimizes some things for you (not clear on which things yet), but lets say I were to do this:
while(true) {
int var = 0;
}
would doing:
int var;
while(true) {
var = 0;
}
take less space? Since you aren't declaring a new reference every time, you don't have to specify the type every time.
I understand you really would only need to put var outside of while if I wanted to use it outside of that loop (instead of only being able to use it locally like in the first example). Also, what about objects, would it be different that primitive types in that situation? I understand it's a small situation, but build-up of this kind of stuff can cause my application to take a lot of memory/cpu. I'm trying to use the least amount of operations possible, but I don't completely understand whats going on behind the scenes.
If someone could help me out, even maybe link me to somewhere I can learn about saving cpu by decreasing amount of operations, it would be highly appreciated. Please no books (unless they're free! :D), no way of getting one right now /:
Don't. Premature optimization is the root of all evil.
Instead, write your code as it makes most sense conceptually. Write it thoughtfully, yes. But don't think you can be a 'human compiler' and optimize and still write good code.
Once you have written your code (more or less naively, depending on your level of experience) you write performance tests for it. Try to think of different ways in which the code may be used (many times in a row, from front to back or reversed, many concurrent invocations etc) and try to cover these in test cases. Then benchmark your code.
If you find that some test cases are not performing well, investigate why. Measure parts of the test case to see where the time is going. Zoom into the parts where most time is spent.
Mostly, you will find weird loops where, upon reading the code again, you will think 'that was silly to write it that way. Of course this is slow' and easily fix it. In my experience most performance problems can be solved this way and 'hardcore optimization' is hardly ever needed.
In the end you will find that 99* percent of all performance problems can be solved by touching only 1 percent of the code. The other code never comes into play. This is why you should not 'prematurely' optimize. You will be spending valuable time optimizing code that had no performance issues in the first place. And making it less readable in the process.
Numbers made up of course but you know what I mean :)
Hot Licks points out the fact that this isn't much of an answer, so let me expand on this with some good ol' perfomance tips:
Keep an eye out for I/O
Most performance problems are not in pure Java. Instead they are in interfacing with other systems. In particular disk access is notoriously slow. So is the network. So minimize it's use.
Optimize SQL queries
SQL queries will add seconds, even minutes, to your program's execution time if you don't watch out. So think about those very carefully. Again, benchmark them. You can write very optimized Java code, but if it first spends ten seconds waiting for the database to run some monster SQL query than it will never be fast.
Use the right kind of collections
Most performance problems are related to doing things lots of times. Usually when working with big sets of data. Putting your data in a Map instead of in a List can make a huge difference. Also there are specialized collection types for all sorts of performance requirements. Study them and pick wisely.
Don't write code
When performance really matters, squeezing the last 'drops' out of some piece of code becomes a science all in itself. Unless you are writing some very exotic code, chances are great there will be some library or toolkit to solve your kind of problems. It will be used by many in the real world. Tried and tested. Don't try to beat that code. Use it.
We humble Java developers are end-users of code. We take the building blocks that the language and it's ecosystem provides and tie it together to form an application. For the most part, performance problems are caused by us not using the provided tools correctly, or not using any tools at all for that matter. But we really need specifics to be able to discuss those. Benchmarking gives you that specifity. And when the slow code is identified it is usually just a matter of changing a collection from list to map, or sorting it beforehand, or dropping a join from some query etc.
Attempting to optimise code which doesn't need to be optimised increases complexity and decreases readability.
However, there are cases were improving readability also comes with improved performance.
For example,
if a numeric value cannot be null, use a primitive instead of a wrapper. This makes it clearer that the value cannot be null but also uses less memory and reduces pressure on the GC.
use a Set when you have a collection which cannot have duplicates. Often a List is used when in fact a Set would be more appropriate, depending on the operations you perform, this can also be faster by reducing time complexity.
consider using an enum with one instance for a singleton (if you have to use singletons at all) This is much simpler as well as faster than double check locking. Hint: try to only have stateless singletons.
writing simpler, well structured code is also easier for the JIT to optimise. This is where trying to out smart the JIT with more complex solutions will back fire because you end up confusing the JIT and what you think should be faster is actually slower. (And it's more complicated as well)
try to reduce how much you write to the console (and IO in general) in critical sections. Writing to the console is so expensive, both for the program and the poor human having to read it that is it worth spending more time producing concise console output.
try to use a StringBuilder when you have a loop of elements to add. Note: Avoid using StringBuilder for one liners, just series of append() as this can actually be slower and harder to read.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. --
Antoine de Saint-Exupery,
French writer (1900 - 1944)
Developers like to solve hard problems and there is a very strong temptation to solve problems which don't need to be solved. This is a very common behaviour for developers of up to 10 years experience (it was for me anyway ;), after about this point you have already solved most common problem before and you start selecting the best/minimum set of solutions which will solve a problem. This is the point you want to get to in your career and you will be able to develop quality software in far less time than you could before.
If you dream up an interesting problem to solve, go ahead and solve it in your own time, see what difference it makes, but don't include it in your working code unless you know (because you measured) that it really makes a difference.
However, if you find a simpler, elegant solution to a problem, this is worth including not because it might be faster (thought it might be), but because it should make the code easier to understand and maintain and this is usually far more valuable use of your time. Successfully used software usually costs three times as much to maintain as it cost to develop. Do what will make the life of the poor person who has to understand why you did something easier (which is harder if you didn't do it for any good reason in the first place) as this might be you one day ;)
A good example on when you might make an application slower to improve reasoning, is in the use of immutable values and concurrency. Immutable values are usually slower than mutable ones, sometimes much slower, however when used with concurrency, mutable state is very hard to get provably right, and you need this because testing it is good but not reliable. Using concurrency you have much more CPU to burn so a bit more cost in using immutable objects is a very sensible trade off. In some cases using immutable objects can allow you to avoid using locks and actually improve throughput. e.g. CopyOnWriteArrayList, if you have a high read to write ration.
I want to make a Java program to help people with basic discrete mathematics (that is to say, checking the truth values of statements). To do this, I need to be able to detect how many variables the user inputs, what operators there are, and what quantifiers there are, if any (∃ and ∀). Is there a good algorithm for being able to do all these things?
Just so you know, I don't just want a result; I want full control over their input, so I can show them the logical proof. (so doing something like passing it to JavaScript won't work).
Okay, so, your question is a bit vague, but I think I understand what you'd like to do: an educational aid that processes first-order logic formulas, showing the user step by step how to work with such formulas, right? I think the idea has merit, and it's perfectly doable, even as a one-man project, but it's not terribly easily, and you'll have to learn a lot of new things -- but they're all very interesting things, so even if nothing at all comes out of it, you'd certainly get yourself some valuable knowledge.
I'd suggest you to start small. I'd start by building a recursive descent parser to recognize zero-order logic formulas (a machine that would decide if a formula is valid, i.e. it'd accept "A ^ B" but it'd reject "^ A ^"). Next up you'd have to devise a way to store the formula, and then you'd be able to actually work on it. Then again, start small: a little machine that accepts valid zero-order logic formulas like TRUE AND NOT (TRUE AND FALSE), and successfully reduces it step by step to true is already something that people can learn from, and it's not too hard to write. If you're feeling adventurous, add variables and make equations: A AND TRUE = TRUE -- it's easy to work these out with reductions and truth tables.
Things get tricky with quantifiers that bind variables, that's where the Automated theorem proving may come into play; but then, it all depends on exactly what you'd like to do: implementing transformations into the various normal forms, and showing the process step by step to the student would be fairly easy, and rather useful.
At any rate, I think it's a decent personal project, and you could learn a lot from it. If you're in a university, you could even get some credit for it eventually.
The technique I have used is to parse the input string using a context free grammar. There are many frameworks to help you do this, I have personally used ANTLR in the past to parse an input string into a descrete logic tree. ANTLR allows you to define a CFG which you can map to Java types. This allows you to map to a data structure to store and evaluate the truth value of the expression. Of course, you would also be able to pull out the variables contained in the data structure.
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.
I realize that to become a better programmer, you need to program!
So obviously the more practice, the better you become.
My problem is this. I am currently in university, and I find my course load is a bit daunting, and I don't have a lot of free time. I don't think I could really take on a big project, particularly I don't think I would have to motivation to see it through, it would be easier just for me to keep putting it off in favour of work that is due is school.
But I still want to practice.
So I am looking for any resources which have programming challenges which can be completed in a fairly small amount of time. Ideally something i could get done in under 10 hours of work (so just over an hour of work each day), if not smaller.
I have heard of Google Code Jam, but I am not sure the length of the programs it specifies, nor the skill level.
Does anyone have suggestions? Even perhaps a compendium of tutorials for different functions might be useful. For example, a tutorial on file IO would be worthwhile (if I didn't already know it), even though it can be a fairly small topic.
You should look into code katas, they do exactly what you are talking about. Short exercises that are designed to perfect your coding/thinking abilities.
Other references:
http://kata.coderdojo.com/wiki/Overview_of_Learning_Resources
Project Euler has some math/number related problems that are very interesting and ranged from easy to very challenging. You can pick your language of choice and submit only the solution (a large integer number). After you submitted the correct solution, you have access to a forum/comment page where others posted their comments and solutions.
From experience I recommend finding a task that you do repetitively and turning it into a program. I also recommend, seriously, re-invent the wheel in order to get practice with programming. Don't let people tell you to not do something just because it exists already. If you don't know how it works, try to write it yourself.
I don't exactly know what programming level you are on, but don't try to do anything too crazy off the bat, that is just a demotivator (such as trying to write a game for the PS3).
If you already can navigate your way around with IO, then you should try to really learn how to use Collections effectively. I think one of the best practice assignments I have ever done was rewriting the Java TreeMap Class. It was a huge challenge and I learned a lot by doing it.
Here are some suggestions for practice assignments:
Take a text file that has a fair amount of information in it, grab anything, you can get something from here if you'd like: http://www.gutenberg.org/ and make a program that will do the following:
Read in the file
Create a collection of words and their occurrences
Create a collection of anagrams
Create a collection of words and the positions in which they occur (line#, word position)
Develop statistics on the words in the file - meaning - treating each word as an individual - which words occur before it and after it.
Remove all of the white space from the file
Write all of the above data to their own files
One of my favorite things to do is mess with web data, go to a polling website, find a page that has poll data in a tabular form and do the following:
Download the data
Parse through the data and turn the tabular data into a CSV file
Open it in excel without error
Or just look for any site and extract data from it, just make sure the site is robot friendly http://www.robotstxt.org/, you don't want any one site to feel like it is under attack. Most of the time though this isn't normally a problem because if you read the site's terms of use it clearly states you are allowed to download 1 copy of whatever it is you are viewing so long as you don't intend to sell it. Of course this changes for every site.
Go to a website and get all of the links off of the page programmatically.
Here is a fun one, the Susan Program (I don't remember why it is named Susan) which I initially wrote using a C program and two Bourne shell scripts in a Unix environment. The idea in this program is to fork 4 child processes and give them each a task like so:
Child 1: Reads in a file, creates a dictionary of each word and its position in the file, this is outputted to a file.
Child 2: Takes Child 1's output and reconstructs the document, this is outputted to a file.
Child 3: Takes Child 2's output and does what child 1 did again
Child 4: Takes Child 3's output and does what child 2 did again
The goal here is to have an exact replica of the original file once Child 4 outputs it. This is challenging and somewhat pointless, but the point of this exercise is to get the practice.
In your case, don't feel that you need to use different threads for this, you can just use a single program with two different functions and just call them in order.
Again, not sure if you are at this level yet, but try to replace any "for" or "foreach" loop you have in your program with recursion, just as practice. Recursion is a pain in the butt, but it is valuable to know and understand.
These are some suggestions which I think will really help you sharpen your skills.
Enjoy
I like SPOJ and Project Euler to take quick programming challenges and exercises.
Code Jam is a good programming contest, although, as you mentioned, most of the problems there aren't for beginners.
There's a good selection of problems from past topcoder algorithm competitions. (They are held ~2 times a month for almost 10 years already, so there're quite a lot.)
Difficulty range from very simple (but still interesting) problems in the 2nd division to very hard.
Additionally, there're editorials with solutions and live environment where you can submit and test your code. You can also learn from submissions by other people.
Check the problem listing.
Another advantage of topcoder is the regular online contests they hold. I find that competing against other people in realtime is a great boost for motivation.
There're many more problem archives, like SPOJ, UVA and Timus, although they rarely provide solutions or even hints.
http://codegolf.stackexchange.com might have some programming challenges to your liking. A lot of the answers on that site are golfed (they implement the program in the least number of characters) but there are definitely some interesting examples to learn from.
Try enrolling on any IT course on the following websites:
Coursera
Edx
Udacity
These websites offer free educational IT programs from prestigious schools wherein there are lot of challenging exercises to sharpen your programming skills. I've learned to program percolation, pattern recognition, bouncing ball and so many more interesting things because of this. You will upload your program upon completion of the exercises and you will be graded accordingly (basically your progam will be checked).
At the end of each course, you will even receive a certificate of completion. Cool Right?
It depends of the language, but in the past http://rubyquiz.com and http://pythonchallenge.com did great for me, also you can join to an open source initiative because usually helps to give you better code review chances.
I've always thought that practicing with sample interview questions was a great way to sharpen one's skills and get exposed to types of problems that you normally wouldn't solve. Plus, if you're going to be looking for a job it helps you even more.
Here's a pretty simple one that I did for fun the other day:
Write a routine to print the numbers 1
to 100 and back to 1 again without
using any loops.
Glassdoor.com has a lot of good interview question submitted by people who actually got them in an interview.
Since you are in University and looking to improve your coding skills the hard-copy book Cracking the Coding Interview might be a good fit for you. It's got great general programming questions and tidbits about interviewing with some of the best companies in tech. Not only are there great questions, but there are decent problem breakdowns as well.
[Disclosure: I own the book but otherwise have no association to it.]
If you like programming and want to improve your programmer skills, you must try cocode.co. It's a social young site, similar to StackOverflow but based on posting and solving programming challenges, instead of asking and answering questions. From very easy challenges to very hard ones.
You can try to solve ACM problems. There are thousands of problems there and you can find the difficulty level so you can choose which problems to do first. The offcial site for this is:
http://uva.onlinejudge.org/. You can learn more there.
regards
arefin
It may seem a little obvious, but I've noticed a real boost in my regular-expressions skills lately just from answering regex questions on Stack Overflow. Teaching forces you to break down problems into easily explainable pieces, and will also guide your research on those occasions where you know most, but not quite all, of a solution.
I suggest finding a topic you're already somewhat proficient in, since this type of thing isn't so good as a beginners' tutorial. Search SO for questions tagged with that topic and try to figure out the answers. Don't just code them in your head; go ahead and write them out, test them, and explain them. If you're not sure your answer is correct, just write it without posting it.
For my university's debate club, I was asked to create an application to assign debate sessions and I'm having some difficulties as to come up with a good design for it. I will do it in Java. Here's what's needed:
What you need to know about BP debates: There are four teams of 2 debaters each and a judge. The four groups are assigned a specific position: gov1, gov2, op1, op2. There is no significance to the order within a team.
The goal of the application is to get as input the debaters who are present (for example, if there are 20 people, we will hold 2 debates) and assign them to teams and roles with regards to the history of each debater so that:
Each debater should debate with (be on the same team) as many people as possible.
Each debater should uniformly debate in different positions.
The debate should be fair - debaters have different levels of experience and this should be as even as possible - i.e., there shouldn't be a team of two very experienced debaters and a team of junior debaters.
There should be an option for the user to restrict the assignment in various ways, such as:
Specifying that two people should debate together, in a specific position or not.
Specifying that a single debater should be in a specific position, regardless of the partner.
If anyone can try to give me some pointers for a design for this application, I'll be so thankful!
Also, I've never implemented a GUI before, so I'd appreciate some pointers on that as well, but it's not the major issue right now.
Also, there is the issue of keeping Debater information in file, which I also never implemented in Java, and would like some tips on that as well.
This seems like a textbook constraint problem. GUI notwithstanding, it'd be perfect for a technology like Prolog (ECLiPSe prolog has a couple of different Java integration libraries that ship with it).
But, since you want this in Java why not store the debaters' history in a sql database, and use the SQL language to structure the constraints. You can then wrap those SQL queries as Java methods.
There are two parts (three if you count entering and/or saving the data), the underlying algorithm and the UI.
For the UI, I'm weird. I use this technique (there is a link to my sourceforge project). A Java version would have to be done, which would not be too hard. It's weird because very few people have ever used it, but it saves an order of magnitude coding effort.
For the algorithm, the problem looks small enough that I would approach it with a simple tree search. I would have a scoring algorithm and just report the schedule with the best score.
That's a bird's-eye overview of how I would approach it.