The Joys Of Programming

First off, Legion is pretty much spot-on in his posts here.

MightyMooquack wrote:

Aside from Unix in general, you will want to become familiar with a number of different kinds of tools. (A key part of the Unix philosophy is dividing software into a large number of tools, which each have a relatively small, well-defined purpose.) The compiler or interpreter for whichever language you are using is an obvious one. A good editor is another one. Version control is a third. As you work more with the language, you will also want to learn how to operate a debugger for it.

Most importantly, be flexible. Don't pigeonhole yourself into any tool, be willing to learn anything and everything. You don't know what you're going to be doing after graduation, so you really don't want to limit yourself to certain things. A bit of knowledge in Linux debugging tools as well as Visual Studio can be more of an asset than just one or the either, especially because most places will be hiring you with the expectation that they're going to need to train you with their stuff.

Also, if you're in a good CS program, most likely, you're going to be doing very little coding for class. Don't worry if you're not doing all that much coding. UIUC's CS curriculum had me learning more math and theory than I ever wanted to know. I use almost all of it now daily, though, so it was definitely worth it.

tuffalobuffalo wrote:

Yeah, that would be a great way to start learning commands and whatnot. It would be way easier to get started than setting up a virtual machine with Linux.

What makes installing a VM "harder" is part of what's valuable as a learning experience.

Installing Linux to a VM is already the made-stupid-easy watered-down way of doing it.

I like Cygwin - I use it whenever I'm in Windows - but I don't think that would be my recommendation for a CS student to learn UNIX. That's more like a POSIX layer on top of Windows than running a full-blown UNIX environment, kernel to userspace.

Frankly, when you're a CS student in college, you're supposed to install Linux onto every piece of electronics you own.

*Legion* wrote:

Mine was waaaaay across campus in the big fancy Education building. :)

Mine was in German class, but was also in the education program. Definitely make sure you have some kind of fun and experiences in college. It is likely the best chance in your life to broaden your horizons.

As to the UNIX stuff: don't be too intimidated. I've been poking at Linux for years. I have multiple Linux LAMP servers I'm responsible for. I *still* get pissed off when some jacktard on the internet says, "It's easy! Just type this: (insert 14 line multi-piped command here) and you'll have exactly what you want."

Also, take the introduction to discrete mathematics class early, and pay attention to it.

*Legion* wrote:
tuffalobuffalo wrote:

Yeah, that would be a great way to start learning commands and whatnot. It would be way easier to get started than setting up a virtual machine with Linux.

What makes installing a VM "harder" is part of what's valuable as a learning experience.

Installing Linux to a VM is already the made-stupid-easy watered-down way of doing it.

I like Cygwin - I use it whenever I'm in Windows - but I don't think that would be my recommendation for a CS student to learn UNIX. That's more like a POSIX layer on top of Windows than running a full-blown UNIX environment, kernel to userspace.

Frankly, when you're a CS student in college, you're supposed to install Linux onto every piece of electronics you own. :)

That is very true. It's also quite fun to setup a virtual machine with Linux. I was just thinking it would be a 5 minute way to let you try out commands.

Also, I am not nearly as experienced and involved in any of these things as most of you guys. So, anything I suggest should be taken with a grain of salt. I enjoy seeing all of the things you guys post in this thread and usually learn something myself.

tuffalobuffalo wrote:

:) That is very true. It's also quite fun to setup a virtual machine with Linux. I was just thinking it would be a 5 minute way to let you try out commands.

That's fair, and one can always do one and move on to the other later.

I just had a very annoying experience with some of my fellow CS students back when I was an undergrad. We had a course that required students to install and run Linux on their systems (or else do all their coursework in the lab, where UNIX systems were provided). Some students threw a fit about this and pinned a whiny letter to the professor's corkboard (every professor's office had a corkboard next to their office door).

I found this completely ridiculous. I think installing Linux onto actual hardware is unquestionably something that one should be able to expect of CS students. Installing to a VM, well, that's even gentler and less demanding.

But I don't wish to argue the point too fiercely. Mainly, I just think of Cygwin as a tool for already-UNIX-experienced programmers to Get Things Done when stuck inside a Windows environment. That may or may not be completely fair. And Fedora is just getting started, not even first-year CS yet.

But Fedora, once you are in, you are required to install and run Linux on a toaster or a Nintendo Wii or something.

*Legion* wrote:

I created a presentation once for my alma mater's CS orientation day.

Some of my "advice to new CS students" bullet points:

* Don't expect to be taught everything in the classroom. You will be expected to study and learn on your own, above and beyond the coursework you're provided. In my school's department, most of our coursework was done in C++, and we did not have a single class on learning C++ the language. That was left as an exercise for the student. CS is not for the student who expects everything they need to know to be handed to them in assignments.

* Don't sell back your textbooks. At least, not very many of them. Provided your department is doing things right, many of the books you buy should end up on your bookshelf for life. Structure and Interpretation of Computer Programs? Introduction to Algorithms? K&R? Yeah, those should be with you until you die.

* Learn UNIX. Even if you love Windows, as a CS student you absolutely should learn to use the power of UNIX when you need it. Linux and other free UNIXes make it trivial to get started. Not to mention the whole experience of using and tinkering with an OS that's an open book instead of a closed-up black box. You can still love Windows afterwards, it's OK.

* Save all your code. I don't think I have a single line of code that I wrote in college, and that sucks. Nowadays, you can get a free Bitbucket account and create private Git repos and store everything up in Bitbucket. Or GitHub if you don't mind having the repos public. You no longer have to set up your own version control server or try and manually manage all your code.

* CS done right is one of the more strenuous college majors, with one of the highest dropout rates. Many departments have tacitly designated "weed-out" courses early in the curriculum, to prevent people who just can't wrap their brain around programming logic from delaying their shift into another field of study. If it's known what and when these courses are at your institution (they usually are known, passed down as lore from outgoing classes to the new incoming ones), be certain you don't overload yourself with too many other classes and responsibilities. Make that semester one of your slightly lighter loads.

* Today, there's a million free online resources from very prestigious universities. If you're not wrapping your head around a concept, look for other resources to see it taught in a different way.

* There are places like StackOverflow where you can ask other programmers questions. When asking questions, especially about code, (a) make an attempt at it first, and (b) show your attempt. People will help you where you're stuck, but nobody wants to do your homework for you.

* Compared to many majors, CS is slightly hardcore, yeah, but it's not a macho exclusive club either. Ignore the people that think they're special because they're in CS. Plenty of other disciplines can be just as strenuous. As long as you have the proper expectations for the amount of work you're going to be doing, and have at least a bit of aptitude for that kind of thinking, it won't be some soul-crushing initiation rite.

Glad I earned my CS degree in 1990. Learning COBOL, PASCAL, and a little of assembler (which I've never used in the real word btw) wasn't so bad.

*Legion* wrote:

I found this completely ridiculous. I think installing Linux onto actual hardware is unquestionably something that one should be able to expect of CS students. Installing to a VM, well, that's even gentler and less demanding.

Haha. Yeah, if you don't have a desire to throw Linux on something, you probably shouldn't be a CS major.

Any recommendations for VM software or setups to use? Have some Unix experience myself from my CS undergrad time, but it would be fun to have an easy to use environment accessible from my PC.

Nuean wrote:
momgamer wrote:

I consider your example a bare minimum proper coding; not as a replacement for commenting. If you're dealing with anything more complicated than Hello, World! that won't cut it. Particularly if you're dealing with complex code across multiple development tiers.

Where is it getting currentAnswer from? The database? A variable assignment above? A code-behind? An object or component? At least tell me type is it -- string, Boolean, numeric? Maybe a note about whether the variable local or global? What comes out of the doSomething function? A string? A return value? What's using it, and what for?

[[removed long stupid code sample]]

You can't put all that in just the variable name. And you make it 10 times worse when you combine a lack of commenting with single letter variable and function names.

Woah slow down!

I don't need to write production ready code to illustrate to Fed that you don't need to comment every line of code you write. I think a bad example and an alternative way of conveying the same information with sane variable names is appropriate. He has been programming for a whole 20 hours now. Anything more and he's going to wonder wtf I'm talking about.

EDIT: I'd consider my examples completely unacceptable coding, not bare minimum proper. :)

I wasn't talking about your sample - I had originally translated your small sample into something with a few more teeth and a try/catch on it. I realized it was overkill and edited it out and left that editorial remark in it's place. Sorry I didn't make that clearer.

Sorry I got all pear-shaped. I've been up since Monday morning, and more than half of this time has been spent rattling the bones and trying to Karnak what b(); does in this )&@% excuse for a transaction system we've been handed. I'm seriously considering adding an expressive comment like this to the top of the form page:

*************************************************************
 *                                                           *
 *   .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-.      *
 *   |                     ______                     |      *
 *   |                  .-"      "-.                  |      *
 *   |                 /            \                 |      *
 *   |     _          |              |          _     |      *
 *   |    ( \         |,  .-.  .-.  ,|         / )    |      *
 *   |     > "=._     | )(__/  \__)( |     _.="  _.="                            "=._ 

Generally, I use my pseudo-code as a framework/first draft for comments. A section at the top of the page/file with general function notes and the global variables laid out. Then a line at the top of the various functions describing the input and output parameters. Top it off with expressive variable names with prefixes that denote their type (like strUserID or bolIsAuthenticated) and that will get you pretty far. Especially if you don't code spaghetti so your functions straggle all over the place.

I also comment my CSS files (looks like /*This is a comment*/) , but I've recently discovered that the newer version of Visual Studio has opinions about that and removes them even though they're part of the base CSS syntax according to the W3C. It also doesn't like trailing semi-colons on the last clause of a style, even though it's a time-honored technique to help prevent cut-and-paste errors. I am NOT amused.

Gunner wrote:

Any recommendations for VM software or setups to use? Have some Unix experience myself from my CS undergrad time, but it would be fun to have an easy to use environment accessible from my PC.

I mostly use VirtualBox, although I am waiting for the Oracle shoe to drop. (I believe the joke is, "Why hasn't Oracle ruined VirtualBox yet? Because they're going in alphabetical order.")

VMWare's desktop products are good if you're looking for a commercial solution. More performant and more features for integrating with the host desktop, but if you just want a VM in a window, VirtualBox does the job nicely.

I have been wanting to play around with KVM, but that doesn't help me when I'm on my Mac.

I've been running a guest Ubuntu in Virtualbox as my main dev environment at work for a while now. It supports using multiple monitors fullscreened, so you can't really tell the difference from a native install most of the time.

Does Unix have it's own language within it or is it just the open OS coded in another language? If so, what is that language?

From a slightly different angle from the above:

Unix's real joy, the thing that makes it so very powerful, is that there is no bright line between users and programmers. On Windows and Mac OS, you are used to being put into an inherently subservient role, where you use graphical programs that have been provided for you, perhaps customizing them somewhat with their internal scripting languages. You have to pay a bunch extra for tools to create those applications, and it is very difficult to go from being a standard user to being able to write those complex apps. The amount of code you have to write to get even a simple application open and talking to a user is staggering. Many toolkits make it easier, but they're just generating the code semi-automatically, it still needs to get written.

On Unix, at least at the default command line, you start with single commands. Gradually, you learn to "pipe" the output from one program to another. Even that is simple programming, and you're doing it already. The Unix philosophy is to provide a bunch of small, absolutely bulletproof, super fast tools, and then let you assemble them in whatever way you find appealing. "Battle tested" doesn't begin to describe how robust the fundamental Unix tools are. I suspect that, at this point, quite a number of them are now perfect code, with zero unknown bugs.

As your skills improve, you can start real scripting. The default command line on most Unix machines these days is "bash", which has a very powerful scripting language built right in. But you can use Python from the command line just as easily as a bash script.

The very first line in a script is the interpreter that makes that script work. So shell scripts will usually start with:

#! /bin/sh (or) #! /bin/bash

which means that text file is to be interpreted with bash. But you can just as easily type in:

#! /usr/bin/perl (or) #! /usr/bin/python

and then the script is run by the perl or Python interpreters. So you can integrate any scripting language cleanly into your working environment. If you like Python, use Python, it's just as good as any other language.

When you graduate (if you ever do) to compiled languages, then you compile a binary and put it in your search path, just like your earlier interpreted programs. They become part of your environment, too. If Unix "has a language", it's probably C, as most system tools are written in it for the best possible speed. But because all languages integrate so nicely with the shell, you can freely use just about anything. Interpreted languages get interpreted, compiled languages get compiled, but it all just runs. You don't particularly care what something is written in, it just works.

In Unix, everyone is a programmer. It's not a matter of whether or not you program, but rather how much of it you do.

The only real downside is that, as immensely powerful as the command line is, it's not as nice for quick visualization and multitasking, so integrating multiple command lines into a graphical UI will give you the best of both worlds.

momgamer wrote:
Dr.Ghastly wrote:
Hypatian wrote:

Next Step: Strong drink.
Next Next step: lookup tables of questions and answers. Comment the crap out of that.
Next Next Next Step: Strong drink. Comment that, too.
Next Next Next next step: lookup tables of functions in which the questions and answers are encoded. Comment. I'm talking the "War and Peace" of comments, here.
Next Next Next next next step: strong drink. Comment some more. (but not "tou drink to cod" )

Fixed for proper programming practices.

Fixed again for even more proper programming practices. I'm in the middle of garbage washing someone else's code today. No comments at all, no white space, topped off with single letter variable names, function names, and some of the CSS styles are named with NUMBERS. It's a damned good thing the dribbling little junk-monkey is in another state.

Yeah that's pretty bad. I have a friend who worked at U-haul for about 3 months. On his second day there after bitching about how all the code sucked and had no comments (Literally none. Yes, literally.) he complained and found out commenting code was strictly forbidden (at least at his branch) and a firing offense. His boss said "Good code comments itself."

Yeah, so heads up on that sh*t for any dev looking at U-Haul.

MacBrave wrote:

Glad I earned my CS degree in 1990. Learning COBOL, PASCAL, and a little of assembler (which I've never used in the real word btw) wasn't so bad.

The sh*tty school I went to gave me 4 COBOL class, 1 VB5 and 1 Java which I had to drop in the 3rd week. Ugh. F COBOL.

When programming, the best advice I ever read was "Remember that while the machine will interpret it, humans have to read it."

Also: you write it once but read it forever after.

momgamer wrote:

...ABANDON ALL HOPE, ALL YE WHO ENTER HERE...

I've actually used that before, in our old rules engine.

That's an awesome thread, Bonus. I'm glad I'm not the only one with ASCII art snippets in my code library.

Just to put snow on the mountain, I found out most of the client-side code in this mess was ummm... borrowed... from something he found online. We were discussing the project this morning and I mentioned some of the strange disconnects in the logic, and that was his explanation. Wuh duh ma huh tah duh fong kwong duh wai shung....

Now that I've handed him off to the guy running the project and am finished breathing into a paper bag, I'm going to get a LOT more coffee and go back to my Daily Planet job while they straighten that out. I'm trying to figure out how to turn one of my Server 2008 R2 test machines into a PDC without jacking everything in my house up. Compared to this, that seems like a clean, simple process at the moment.

Malor wrote:

The only real downside is that, as immensely powerful as the command line is, it's not as nice for quick visualization and multitasking, so integrating multiple command lines into a graphical UI will give you the best of both worlds.

Have you learned the power of the greatest remote shell tool ever: Screen? It cured my cancer AND made me more attractive to the opposite sex.

Dear Java,
"workaround" != "fix"
Your compiler still crashes when it should not! Don't claim a bug report as 'fixed' because a sh*tty workaround exists!
Sincerely yours,
Mixolyde

Mixolyde wrote:

Dear Java,
"workaround" != "fix"
Your compiler still crashes when it should not! Don't claim a bug report as 'fixed' because a sh*tty workaround exists!
Sincerely yours,
Mixolyde

I presume you are talking about Java 7? I won't be using it until it gets to update 5 or 6. Heard too many bad things about it. I really want to start using the new catch.

Nope, it's 1.6.0_29, and it's been in since they added Annotations in 5.

Basically, if you compile Class A that has annotation X, you need the jar with Annotation X in your classpath. Fine.

If you try to compile Class B, that depends on Class A, you need Class A and ALSO need the jar with Annotation X in your classpath in order to compile. Even though you're not compiling Class A, or anything that directly has Annotation X. Otherwise you crash the compiler. Fun times.

The "workaround" is just to add that jar with X to your classpath, but I'm maintaining 15 more or less separate projects with various dependencies on things with annotations, and don't want copies of libraries in multiple spots, and cluttering up build script dependencies where they don't belong.

Which I wouldn't have to do if I wasn't being told how to develop software by electrical engineers and process wonks.

You obviously need more process.

/ducks

Dr.Ghastly wrote:

The sh*tty school I went to gave me 4 COBOL class, 1 VB5 and 1 Java which I had to drop in the 3rd week. Ugh. F COBOL.

It served me well the first 10 years or so of my career. At my current workplace I still find myself having to look at COBOL code every once in a while, although it's definitely not what I do on a daily basis.

Mixolyde wrote:

Nope, it's 1.6.0_29, and it's been in since they added Annotations in 5.

Basically, if you compile Class A that has annotation X, you need the jar with Annotation X in your classpath. Fine.

If you try to compile Class B, that depends on Class A, you need Class A and ALSO need the jar with Annotation X in your classpath in order to compile. Even though you're not compiling Class A, or anything that directly has Annotation X. Otherwise you crash the compiler. Fun times.

The "workaround" is just to add that jar with X to your classpath, but I'm maintaining 15 more or less separate projects with various dependencies on things with annotations, and don't want copies of libraries in multiple spots, and cluttering up build script dependencies where they don't belong.

I am assuming you are using Apache Ant to compile your project? I know that there is a lot of controversy over which build tool to use and which is better, but in this case I would recommend using Apache Maven to build your project. Maven has built in dependency management and when an artifact is labelled as a compile time dependency, all dependent modules will inherit this compile time dependency without the person managing the module even know it is there.

If Maven is to big of a change, you can use Ivy to get dependency management while keeping Ant as the build tool.

Some days, programming feels like white magic. Other days it feels like blood magic...

MacBrave wrote:
Dr.Ghastly wrote:

The sh*tty school I went to gave me 4 COBOL class, 1 VB5 and 1 Java which I had to drop in the 3rd week. Ugh. F COBOL.

It served me well the first 10 years or so of my career. At my current workplace I still find myself having to look at COBOL code every once in a while, although it's definitely not what I do on a daily basis.

I got out in 97.

Have you learned the power of the greatest remote shell tool ever: Screen?

I use it all the time, but rarely for multitasking -- rather, I use it to isolate long-running console sessions from a given network connection. If I start a process from one machine, running it under screen means it won't crap out, even if the source machine is disconnected. And I can always check on its progress from other remote machines without interfering with its execution.

Screen is perfectly capable of managing multiple programs, but I find it less intuitive than just running a couple of tabs in a shell window (or separate shell windows, if I need to have them side-by-side). It becomes one mouse click to change contexts instead of the process of 'putting away' a session and 'recovering' the session I want to work with.

I think a lot of its power only really shows when you have a very narrow pipe to the Internet, and need to run multiple programs remotely. That still happens sometimes, but it's not that common anymore. When most folks can easily have VMs running a Unix, and have multi-megabit connections going both ways, it's screen's ability to insulate you from network burps that's most useful.

Oh, for those of who you don't know: screen is a session virtualizer. You start screen, and it by default just gives you a prompt back, but now any programs you're running are attached to an invisible "screen" terminal, instead of the tty associated with your login.

Normally, when you disconnect a network session, that tty is closed, and any programs dependent on it will usually die, so if you start a long complex calculation*, and the network drops, you can lose a lot of work. Screen daemonizes itself, basically inserting itself as a shim between your real tty and the ones your programs are using. It allows you to have multiple virtual consoles and to swap between them freely, and it keeps running no matter what happens to your network connection. Even if you lose connection, programs just serenely drive the virtual TTY, and screen keeps track of what that TTY is displaying. When you reconnect from a new client, it duplicates the virtual TTY to your real one, and then feeds your input back.

It feels exactly the same as running any other remote session, except it lets you run a ton of stuff simultaneously, all of which will run until you kill the programs or screen itself. Your presence or absence, network-wise, is not visible to the programs in question. They just drive a virtual screen, and sometimes that virtual screen is displayed on one or more remote terminals, but the programs can't tell when or if that's happening.

It's a VERY clever program.

* Nethack, say, or Crawl. Important stuff.

Yeah, I use it more for the remote session saving in case of network loss use case than anything else. It's not at useful when you're on a local desktop environment.

kazar wrote:

I am assuming you are using Apache Ant to compile your project? I know that there is a lot of controversy over which build tool to use and which is better, but in this case I would recommend using Apache Maven to build your project. Maven has built in dependency management and when an artifact is labelled as a compile time dependency, all dependent modules will inherit this compile time dependency without the person managing the module even know it is there.

If Maven is to big of a change, you can use Ivy to get dependency management while keeping Ant as the build tool.

Yeah, we're using Ant. Which is fine, I love Ant for doing single projects. Maven would be orders of magnitude better for this, but the process to get it approved, get people to switch to it, get the prime to install and use it would actually be more time consuming and painful than just copy and pasting a dependency that shouldn't even exist around to a dozen build files.

The "Joys" of Programming, indeed.