Options are used to provide extra information to tune or customize the execution of a program. In case it wasn't clear, options should be optional. A program should be able to run just fine with no options whatsoever. (Pick a random program from the Unix or GNU toolsets. Can it run without any options at all and still make sense? The only exceptions I can think of are find, tar, and dd--all of which are mutant oddballs that have been rightly criticized for their non-standard syntax and confusing interfaces.)
Lots of people want their programs to have ``required options''. Think about it. If it's required, then it's not optional! If there is a piece of information that your program absolutely requires in order to run successfully, that's what positional arguments are for. (However, if you insist on adding ``required options'' to your programs, look in ``Extending Examples'' (section 6.20.5) for two ways of implementing them with optparse.)
Consider the humble cp utility, for copying files. It doesn't make much sense to try to copy files without supplying a destination and at least one source. Hence, cp fails if you run it with no arguments. However, it has a flexible, useful syntax that does not rely on options at all:
$ cp SOURCE DEST $ cp SOURCE ... DEST-DIR
You can get pretty far with just that. Most cp implementations provide a bunch of options to tweak exactly how the files are copied: you can preserve mode and modification time, avoid following symlinks, ask before clobbering existing files, etc. But none of this distracts from the core mission of cp, which is to copy one file to another, or N files to another directory.
See About this document... for information on suggesting changes.