
[…] is how a user interacts with and experiences a product, system or service. It includes a person’s perceptions of utility, ease of use, and efficiency. — Wikipedia
[…] focuses on understanding user behaviors, needs and motivations through interviews, surveys, usability evaluations and other forms of feedback methodologies. — Wikipedia
is what makes a user want to use a product

[…] is the art and technique of arranging type to make written language legible, readable and appealing when displayed. — Wikipedia


apply a consistent layout and visual design
git --help
usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[--config-env=<name>=<envvar>] <command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
...
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.Use sensible defaults (if at all)
Don’t lie :)
Make it easy to do things right
How do you get out?
Which button opens the door?
is what makes a user enjoy to use a product
[…] the capacity of a system […] to perform the tasks safely, effectively, and efficiently while enjoying the experience. — Wikipedia
… and more fun! :)
use standard formats, preferably machine readable
Configurations can usually be set on different levels
/etc)~/.config)GNU style syntax following POSIX guidelines
-i--input--version and --helpRewrite safe_copy.py1 to use intuitive argument names, then make it more intuitive.
import argparse
import os
import shutil
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("-I", "--outfIle", help="Where to copy")
parser.add_argument("-O", "--sOurce", help="Source file")
args = parser.parse_args()
return args
def copy_file(args):
if not os.access(args.outfIle, os.F_OK):
shutil.copyfile(args.sOurce, args.outfIle)
if __name__ == "__main__":
args = parse_args()
copy_file(args)import argparse
import os
import shutil
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--infile", help="Where to copy from", required=True)
parser.add_argument("-o", "--outfile", help="Where to copy to", required=True)
args = parser.parse_args()
return args
def copy_file(args):
if not os.access(args.outfile, os.F_OK):
shutil.copyfile(args.infile, args.outfile)
if __name__ == "__main__":
args = parse_args()
copy_file(args)-i with long version --infile for the input file-o with long version --outfile for the output filerequired=True triggers error message when called without argumentsimport argparse
import os
import shutil
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("infile", help="Where to copy from")
parser.add_argument("outfile", help="Where to copy to")
args = parser.parse_args()
return args
def copy_file(infile, outfile):
if not os.access(outfile, os.F_OK):
shutil.copyfile(infile, outfile)
if __name__ == "__main__":
args = parse_args()
copy_file(args.infile, args.outfile)-- in front of the argument, and no short version means these arguments become positional and are required by default.copy_file.py INFILE OUTFILE (just as cp)What could go wrong?
The try-except-else statement lets you handle exceptions
Take safe_copy.py and add useful error messages and return codes.
If the target file exists, we raise a FileExistsError.
The caller can decide whether that’s a problem or not.
An uncaught exception will end the program with return code 1.
safe_copy.py explanationsargparseCreate a parser for command line arguments
shutilCall shutil.copyfile() to do the actual copying
This code is only executed, when run as a script (e.g. by using python3 safe_copy.py), but not when loaded with an import safe_copy.