I have done a series of posts on Microsoft Excel, targeted largely at beginners, and/or those who use Excel casually and seek to expand their skills a little. MS Excel is a powerful program, which has a host of advanced analytical and math functions, for those who spend a moment exploring them.
What is important about using excel to maximum effect is not remembering how to use each specific function of formula - it is enough to understand the syntax excel requires, and to realize that if you can dream up a use-case, there is most likely a built-in function which can do what you need.
Here, I have combined all of my Excel-related posts to date to make it easy to find what you might need. More will follow. If you have a specific request, let me know, and I will do my best to create a post addressing the topic you are interested in.
This area was created specifically for Mary (you know who you are) to begin with, a friend who has applied herself to the pursuit of learning and personal growth. Mary, you inspire! Hopefully, others will benefit as well.
Links to Excel Articles on this blog:
More links will follow, including some to useful resources outside this site. Lastly, remember, for all things related to tech, programming, and math functions, Google is your friend. Use it!
This is the second installment of a multi-part series about getting your feet wet with Git for Windows Developers. If this is your first time here, you may want to review Part I of the series.
If you have been following along so far, you likely have by now installed msysgit on your development machine, and performed the initial configuration necessary to begin using git to track changes in your source code. So, what next?
Well, before we can do much with Git, we need to make sure we have at least a token familiarity with using the Bash command prompt. To do this, we will walk through some basic commands related to navigating in bash, getting information about the file system and environment, and working with directories and files. All of these are necessary in order to work with Git using the Bash command line.
Since these posts can get long (due in large part to the large number of screen shots), this may span a few posts. It’s not as bad as it looks, really. Lots of pictures.
If you are already familiar with the concepts here, and mainly just need help with the proper syntax for performing these actions in Bash, refer to my Basic Git Command Line Reference Post which contains a listing of the most common git and Bash commands without all the narrative.
Otherwise, read on, and let’s get comfortable using the Bash command line in a Windows environment.
Get Acquainted with Bash
The Bash command line comes from a Unix heritage, and even if you are familiar with the Windows command line, or Powershell, using Bash is different.
First, we should get a little comfortable moving around our file system and performing basic tasks with files and directories.
When you first open the Bash command window, you should see something like this:
In the above, the text in green is the User Name and Computer Name, displayed using the convention UserName@ComputerName. The curlicue character following means that we are in our default directory (or folder), usually our Windows User Folder.
A line which begins with the default prompt (in this case, a $ symbol) is a line on which you will enter a command. Lines without the $ symbol will represent feedback from the system. Each time you type in a command and hit enter, Bash will execute the command, return whatever output (if any) and the leave you with a new prompt.
Note that many commands simply execute, and there is no output. It is a principle amongst Linux programming that a good program executes silently, and only provides feedback if requested, or if something has gone wrong. More on this momentarily.
List the Directories within the Current Folder
We can list other directories within our current folder using the ls command. Type ls into your Bash window and hit enter:
Use Bash to list the contents of the current directory:
Huh. That’s a lot of stuff, and except for those items with file extensions, it is hard to tell what is a directory (folder) and what is a file of some sort. Wouldn’t it be nice to show just the folders, without the other stuff?
In a clear case of stating the obvious, the following will clear your Bash window. Type this and hit enter:
Clear the Bash window:
Now, let’s try to examine the folders in our current directory again, and see if we can get a more useful view of the subfolders we are working with. Type the following command into the Bash window, and hit enter again:
Print a listing of all directories within the current directory:
$ ls -d */
The result should look like this:
That’s a little more like it. Ok, so now we can see what folders exist within our current directory.
For a cleaner listing of the variations for the ls command, see the Show Directory Contents section of my Basic Git Command Line Reference Post.
Create a New Directory in the Current Directory
Next, let’s create a new folder. The command for creating a new directory is as follows:
Create a new directory within the current directory:
$ mkdir NewFolderName
Type that into your Bash window, substituting MyNewFolder for NewFolderName and hit enter. This is what you should see when you are done:
But hey - nothing happened, right? Wrong.
As mentioned above, when the mkdir command executed properly, the result is “silence.” In other words, Bash assumes YOU know that, lacking additional feedback, everything went fine. Let’s check and see. Type your new “Show me all the folders, but only the folders” command we discussed previously, and hit enter:
Well, what do you know. There is our new folder. But wait. What if we want spaces in the name of our folder? Let’s try THAT with a another new folder. Type the following and hit enter:
Create a folder named My Other New Folder:
$ mkdir My Other New Folder
When you hit enter, you should see something like this:
Hey, looks like everything worked! No complaints from Bash. Let’s see, using our “Show directory contents” command again:
Uh-oh. Looks like things didn’t go quite the way we expected. As it turns out, we confused Bash, because the actual syntax of the mkdir command is:
The full syntax for the mkdir command:
$ mkdir Folder_1 Folder_2 . . . Folder_n
So when we typed in a folder name containing spaces, Bash thought we were creating a separate new folder for each word. As it turns out, most of the time when using Bash, we need to enclose text with spaces in quotes, so that Bash will know that the quoted text represents a single object or idea. Let’s try creating our new folder with spaces in the name again. This time, type the following into the Bash window:
Create a new folder with spaces in the name:
$ mkdir "My Other New Folder"
When you are done, you should see something like this:
Again, we assume that nothing went wrong from a technical standpoint, because Bash executed the command and returned without complaint. If we check to see again, we find the following:
Yay! So now we can not only create folders, but with spaces in the names too, dammit!
For more on creating directories, see the Creating New Directories Section in my Basic Git Command Line Reference Post
Move to a Folder Within the Current Directory
Ok, so now let’s navigate ourselves into the first folder we created, MyNewFolder. First, though, let’s clear the bash window again, so we can get rid of all the clutter we have accumulated so far.
When we want to move to a new location using Bash, we use the cd command:
The correct syntax for this command is:
Change Directory Command Syntax:
$ cd [options] [<DirectoryName>]
In the above, the square brackets denote optional inputs, and the angle brackets denote user-supplied values. In both cases, we do not type the actual brackets into the command window.
Since Bash already knows the current directory we are in, we can specify a folder name which exists in the current directory, without the rest of the directory path. Type the following into the Bash window, and hit enter. You should see something similar to this:
Note in the above that the line above our prompt has changed, and appears to indicate our current path as:
Remember that Bash uses the ~ symbol to denote our default (User) directory, so this is a relative reference within the user directory. From where we are right now, there are a number of ways we could return to the user directory.
The first is to simply enter the cd command with no additional input. Doing this will return us to the default directory from wherever we happen to be in the file system:
Return to the Default Directory (“Take Me Home”)
Another option is to type cd - (that’s the cd command followed by a space, followed by a single dash). This tells bash to go back to the previous directory. In this particular case, the previous directory also happens to be our home user folder, but it really doesn’t matter what directory we came here from, cd - returns us there.
Return to the Previous Directory (“Take Me Back”)
$ cd -
The third option is to type cd .. (that is the cd command, followed by a space, followed by two periods in a row). This command tells bash to go up one level in the folder hierarchy.
Move Up One Level (“Take Me Up”)
$ cd ..
Considering that we are currently in a folder within our home directory, you can see why in the current situation, these three are all about the same in terms of returning to the home directory. At the moment, it is not only the last place we navigated from, but is also one level above our current location. And it is, indeed the home folder. So all three options work for us in this case. Try the “Take Me Up” command. Type it into your Bash window and hit enter. You should see something like this:
Note that we now appear to back in the “directory known as ~” or, our user folder.
Now type the “Take Me Back” Command (cd -) and hit enter:
Now, here we are right back in the MyNewFolder directory. Note that Bash decided to tell us where it took us in long form:
A Linux-Style Directory Path
But wait - what is with that funny directory syntax? That is the Linux directory style. In fact, when typing explicit directory paths into Bash, you will need to use that format, because Bash will not recognize the Windows directory style. It’s easy enough to follow though:
- Instead of using the forward-slash (\) character as a path delimiter, Bash (and Linux) uses the backslash (/)
- /c/ is the Linux way of expressing the familiar C:\
Move to a Specific Directory Using the Complete Directory Path
Knowing this, we can also use explicit paths for navigation. For example, let’s say I wish to move from the current directory to my Documents folder. I can type the following:
Move to a specific directory using the directory path:
$ cd /c/Users/CurrentUserFolder/Documents
Try that now, substituting your user folder, assuming that you have a standard Windows file structure, which includes a Documents folder in your user folder by default:
Ok. If all went well, you should now find yourself in your Documents folder. Note that even though you are within a subfolder of your user folder, Bash is now displaying the long form of the directory path, instead of the shorthand relative path.
Now try using the “Take Me Home” version of the cd command (simply type cd and hit enter):
Presto - back in our home directory.
For more on directory navigation, see the Navigating the File System Section of my Basic Git Command Line Reference Post
Ok, now what about those folders we “accidentally” created when we entered a multi-part directory name? You know, the folders named “My” and “Other” and “New” and “Folder”? Remember THIS:
Since these folders are all empty, we can simply use the rmdir command:
Remove One or More Empty Directories:
$ rmdir Directory_1 Directory_2 . . . Directory_n
Type the rmdir command as follows and hit enter. When you are done, you should see something like this:
Then, if we check the directory contents again, we see that those extra directories no longer exist:
Removing an empty directory or directories is a simple undertaking. The process is a little different if the directory to be removed contains files or other directories. We’ll look at this in the next post.
Next: Creating and Working with Files using Bash
John on Google
While there are GUI interfaces available for GIT (some good, some bad), familiarity with at least the basics of git’s command line interface can only enhance your ability to use the tool to maximum effectiveness. Since I am relatively new to git and version control in general, I set out to learn the basics of the git command line. In doing so, I found it handy to keep a list of the commonly-used commands nearby so that I didn’t have to keep Googling.
In this post, I am going to cover the very basic set of commands one might require to effectively navigate and maintain your source repo using only the git Bash command line interface. Probably, in creating this post, I will not need to look at this again, as the sheer fact of composing this list and explaining it all will burn these into my brain forever. On the other hand, if I am ever unsure, I will now have a place to come look!
NOTE: The references here are by no means comprehensive. I have included the basic commands required to get started, and the commonly used options for each command. There is a wealth of additional information available on the internet, and I have included some helpful reference links at the end of this post.
To more easily find what you might be looking for, here are some links to specific sections of this post:
Working with the file system
Configuring Git and Creating a Repository:
Staging and Committing Changes
Working with Remote Repositories (like Github)
Undoing Changes and Working With Tags
Git Bash: Syntax Notes
First off, note that Git Bash is a *nix application (Unix/Linux), and expects inputs according to *nix conventions when it comes to file system navigation. This is important when using Git on a windows system, because we need to mentally map the familiar Windows directory notation to Unix format:
|Windows Directory Path
||<---- Becomes ----->
||*nix Directory Path
Strings with Spaces
When we are going to provide an input string with no spaces, we need do nothing. However, strings which contain spaces must be enclosed in quotes. Remember this. Personally, I just use quotes around strings in general.
The “Home” Directory
The file system in *nix systems is set up a little differently than in Windows. Git Bash assumes the existence of a “home” directory for each user. In Windows, the default is your personal user folder. This folder is where Git Bash opens by default. Typing only cd after the command prompt will always return you to the root level of the home directory.
Command Syntax Format:
The basic command syntax for a git Bash Command is:
$ CommandName [options] [directory]
In the above, the square brackets denote optional parts of the command. The square brackets themselves are not typed into the command line. Items following a command which are not enclosed in brackets are required.
Cases and Spaces Count
Also note that git Bash is case-sensitive, and spaces count. For Example, the common command to change to another directory is cd. This is NOT the same as CD or Cd.
When portions of a command are optional, we will note this by enclosing them in square braces:
$ Command [options]
In the above, we do type the square brackets.
For our purposes here, when we are presenting command syntax examples, we will denote user-provided values between angle brackets:
$ Command [options] <SomeUserInput>
In the above, we do type either the square or angle brackets.
Git Bash: Navigating the File System (cd)
cd [options] [<directory>]
Navigate to the Home Directory (Default folder for the current user):
Navigate to a specific folder in the file system:
$ cd /c/SomeFolder/SomeOtherFolder/
Navigate to a specific folder in the file system (if there are spaces in the directory path):
$ cd “/c/Some Folder/Some Other Folder/”
Go back to the previous Location:
$ cd -
Move Up One Directory Level:
$ cd ..
In the above, the cd command is followed by a space, then two period with no space between.
Git Bash: Show Directory Contents (ls)
-1 = List 1 item per line
-r = Reverse the sort order
-a = Show Everything, including hidden items
-d = list only directories
-l = (letter L, lowercase) = Use a long listing format (more info per item, arranged in columns, vertical listing)
List the contents of the current directory (folder):
The above will display the contents of the current directory as a horizontal list. Not real convenient.
List the contents of the current directory, one item per line:
$ ls -1
That’s better. Note, however, that we can only differentiate files from subdirectories based upon the file extension.
List only the subdirectories (folders) within the current directory:
$ ls –d */
List everything in long form, vertically:
$ ls –al
The above gives a swath of information. Also, subdirectories are differentiated by the first column (begin with drwxr instead of -rw)
List all contents, including subdirectory contents, single item per line:
$ ls -1 *
Git Bash: Create a New Directory (mkdir)
mkdir [options] <folderName>
-p = Create parent directories as needed
--verbose = Show a message for each new directory created (note the double dash)
Create a folder in the current directory (without spaces in the folder name):
$ mkdir NewFolderName
Create a folder in the current directory (with spaces in the folder name):
$ mkdir “New Folder Name”
Create a folder at the specific directory path:
$ mkdir /c/ExistingParentFolder/NewFolderName
Create a folder at the specific directory path, and create parent directories as needed:
$ mkdir -p /c/NewParentFolder/NewFolderName
Create a folder at the specific directory path, create parent directories as needed, and print a description of what was done in the console window:
$ mkdir -p --verbose /c/NewParentFolder/NewFolderName
Git Bash: Create Files (touch, echo)
touch [options] <FileName>
echo [options] TextString > FileName
(NOTE: FileName can include directory. Default is the current directory).
Create a single (empty) text file in the current directory:
$ touch newFile.txt
Create a single (empty) text file in the specified directory:
$ touch /c/SomeFolder/newFile.txt
Create multiple (empty) text files in the current directory:
$ touch newFile_1.txt newFile_2 . . . newFile_n
Append text to a file. If the file does not exist, one is created:
$ echo “This text is added to the end of the file” >> newFile.txt
Overwrites text in a file. If the file does not exist, one is created:
$ echo “This text replaces existing text in the file” > newFile.txt
Overwrites text in a file at the specified location. If the file does not exist, one is created:
$ echo “This text replaces existing text in the file” > /c/SomeFolder/newFile.txt
Git Bash: Remove Files (rm)
rm [options] -<FileName>
-I (or --interactive) = Prompt before removal
-v (or --verbose) = Explain what is being done
Remove the specified file from the current directory (no spaces):
$ rm -DeleteFileName
Remove the specified file from the current directory (with spaces):
$ rm -“Delete File Name”
Prompt for confirmation before remove the specified file from the current directory (no spaces):
$ rm -i -DeleteFileName
Removes the specified file and reports what was done in the console window:
$ rm -v -DeleteFileName
Git Bash: Remove Directories (rmdir, rm -rf)
rmdir [options] <FolderName>
Removes the specified folder if empty. Operation fails if folder is not empty:
$ rmdir -DeleteFolderName
Removes the specified folder and all contents:
$ rm -rf -DeleteFileName
Git Bash: Configure Git (git config)
git config --global user.name <“User Name”>
git config --global user.email <UserEmailAddress>
Set the global User.Name value for the current user on the system:
$ git config --global user.name “FirstName LastName”
Set the global User.Email value for the current user on the system:
$ git config --global user.email UserEmailAddress
Show me the current values:
The following return the current values for the user.name and user.email properties respectively and output the values to the console window:
Print the current global User.Name value to the console window:
$ git config --global user.name
Print the current global User.Email value to the console window:
$ git config --global user.email
Git Bash: Initialize a New Git Repo (git init)
Create files required in the current directory to perform version control:
$ git init
Git Bash: Add/Stage for Commit (git add)
git add [options] [<File_1>] [<File_2>] . . . [<File_n>]
-A (or --all) = Add all new or changed files to the staged changes, including removed items (deletions)
-u = Add changes to currently tracked files and removals to the next commit. Does not add new files.
. = Adds new or changed files to the staged changes for the next commit, but does not add removals.
Note that git add -A is semantically equivalent to git add . followed by git add –u
-p = Interactive add. Walks through changes in the working directory and prompts for add
Add all changes in the working directory to the next commit, including new files and deletions:
$ git add -A
Add all changes to tracked files and all new files to the next commit, but do not add file deletions:
$ git add .
adds all changes to tracked files and all file removals to the next commit, but does not add new files:
$ git add -u
Walks through changed files and prompts user for add option. Does not include new files:
$ git add -p
Git Bash: Unstage from Commit (git reset)
git reset HEAD <File_1>
Remove the specified file from the next commit:
$ git reset HEAD FileName
Git Bash: Committing Changes (git commit)
git commit [options] [<File_1>] [<File_2>] . . . [<File_n>] [-m <“Commit Message”>]
-a = Commit all changes to tracked files since last commit
-v = Verbose: include the diffs of committed items in the commit message screen
--amend = Edit the commit message associated with the most recent commit
--amend <File_1> <File_2> . . . <File_n> = redo the previous commit and include changes to specified files
Commits the changes for the specific file(s) and includes the commit message specified:
$ git commit FileName –m “Message Text”
Note that Git requires a commit message. If you do not provide one using the -m option, you will be prompted to do so before the commit is performed.
Commits all files changed since last commit. Does not include new files.
$ git commit –a –m “Message Text”
Adds all changes to the previous commit and overwrites the commit message with the new Message Text. Does not include new files:
$ git commit –a –amend –m “Message Text”
Git Bash: Remote Repositories (git remote)
git remote add <RemoteName> <RemoteURL>
git remote show <RemoteName>
NOTE: As used here, RemoteName represents a local alias (or nickname) for your remote repository. The name of the remote on the server does not necessarily have to be the same as your local alias.
Add the specified remote repo to your git config file. The remote can then be pushed to/fetched from:
$ git remote add RemoteName https://RemoteName/Proj.git
Print information about the specified remote to the console window:
$ git remote show RemoteName
Git Bash: Branching (git branch)
git branch [options][<BranchName>][<StartPoint>]
-a = List all local and remote branches
-r = List all remote branches
List all local branches:
$ git branch
List all remote branches:
$ git branch -r
List all local and remote branches:
$ git branch -a
Create a new branch starting at the some point in history as the current branch:
$ git branch BranchName
Note that this creates the new branch, but does not “check it out” (make it the current working branch).
Switch from the current branch to the indicated branch:
$ git checkout BranchName
Create a new branch and switch to it from the current branch:
$ git checkout –b NewBranchName StartPoint
Note that StartPoint refers to a revision number (or the first 6 characters of such) or an appropriate tag.
Git Bash: Merging Branches
git merge [<BranchName>][--no-commit]
Merge the specified branch into the current branch and auto-commit the results:
$ git merge BranchName
Merge the specified branch into the current branch and do not commit the results:
$ git merge BranchName --no-commit
Git Bash: Pushing to Remote Repositories (git push)
git push [<RemoteName> <BranchName>]
Update the remote server with commits for all existing branches common to both the local system and the server. Branches on the local system which have never been pushed to the server are not shared.
$ git push
Updates the remote server with commits for the specific branch named. This command is required to push a new branch from the local repo to the server if the new branch does not exist on the server.
$ git push RemoteName BranchName
Git Bash: Fetching from Remote Repositories (git fetch)
git fetch <RemoteName>
Retrieve any commits from the server that do not already exist locally:
$ git fetch RemoteName
NOTE: git fetch retrieves information from the remote and records it locally as a branch in your current repository. In order to merge the new changes into your local branch, you need to run git fetch followed by git merge. Since there may be more than one branch on the remote repository, it is necessary to specify the branch you wish to merge into your current branch:
Merge syntax for post-fetch merge:
git merge <RemoteName/BranchName>
Merge the newly fetched branch from the remote into your current working branch:
$ git merge RemoteName/BranchName
Using fetch before merging allows you to pull changesets in from the remote, but examine them and/or resolve conflicts before attempting to merge.
Git Bash: Pulling from Remote Repositories (git pull)
git pull <RemoteName/BranchName>
Fetch changes from the specified branch in the remote, and merge them into the current local branch:
$ git pull RemoteName/BranchName
NOTE: git pull is essentially the same as running git fetch immediately followed by git merge.
Git Bash: Undo (git reset)
git reset [options]
--hard = undo everything since the last commit
--hard ORIG_HEAD = Undo most recent merge and any changes after.
--soft HEAD^ = undo last commit, keep changes staged
Undo everything since the last commit:
$ git reset --hard
Undo most recent successful merge and all changes after:
$ git reset --hard ORIG_HEAD
Undo most recent commit but retain changes in staging area:
$ git reset --soft HEAD^
Git Bash: Tags (git tag)
git tag [options] [<TagName>] [<CommitChecksum>] [<TagMessage?]
-a = Annotated Tag
-m = Annotated Tag Message
List all tags in the current repository:
$ git tag
Create a tag at the current revision:
$ git tag TagName
Create a tag at the commit specified by the partial checksum (six characters is usually plenty):
$ git tag TagName CommitChecksum
Create an annotated tag:
$ git tag -a TagName -m TagMessage
Create an annotated tag at the commit specified by the partial checksum:
$ git tag -a TagName CommitChecksum
Push tags to a remote repository:
$ git push --tags
Print information about a specific tag to the console window:
$ git show TagName
Almost all of the information presented above represents a “toe in the water” sampling designed to get started. There are plenty more commands for use both within Git itself, and from the more general Bash command line. Additionally, most of the commands listed here have more options than I have included. I tried to keep this simple, as a reference for myself, and for whoever else may find it useful to get started with the basics.
John on Google
. . . Or, why the STL ALT.NET User Group kicks so much ass.
One of the best moves I ever made was getting involved with a developer user group, or “meet up” as they are sometimes known. Here’s why.
I am a self-taught developer, having been touched by the progressive disease of code addiction a few years back, in conjunction with a project at work. I have had to learn most of this addictive trade the hard way, e.g. long bouts of going down the wrong road to a solution, and hours spent surfing the web, seeking solutions to problems which, for an experienced dev, would be rudimentary.
In all this, I have learned much.
One of the biggest lessons I learned is, hijack the education and experience of others, by whatever means necessary. The other thing I learned is the old saw “when all you have is a hammer, everything looks like a nail.” I’ll come back to this in a minute.
I had lived in Portland, Oregon for most of the past nine years. As my coding addiction grew worse and worse, I found myself joining some local user groups, and regularly attended the PADNUG (Portland Area Dot Net Users Group, of course). I found here a group of like-minded individuals, who all spoke the same language (that would be C#, for the most part, but I will generalize and use “.NET” to represent all the .NET languages – yes, I KNOW .NET is a framework, not a language, but this is MY blog, and I can call things what I want!).
I moved, rather suddenly, from Portland to St. Louis, Missouri in October of 2011. Before I was on the ground more than 24 hours in my new neighborhood of Clayton, I was scouring the inter-webs for the St. Louis version of the PADNUG. I found the Saint Louis ALT.NET group. Upon following the Google link to the group’s home page, the very first thing I saw was THIS:
“The ALT.NET community is a loosely coupled, highly cohesive group of like-minded individuals who believe that the best developers do not align themselves with platforms and languages, but with principles and ideas. “
See my previous note about hammers and nails.
I loved this. As I continued my scan of the page, I found the following list, describing the “Alt.Net philosophy” espoused by David Laribee:
The alt.net Philosophy
“1. You're the type of developer who uses what works while keeping an eye out for a better way.
2. You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
3. You're not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
4. You know tools are great, but they only take you so far. It's the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles (e.g. Resharper.)
The STL ALT.NET Meetup
The St. Louis ALT.NET meetup group is a place where .NET developers can learn, share, and critique approaches to software development on the .NET stack. We cater to the highest common denominator, not the lowest, and want to help all St. Louis .NET developers achieve a superior level of software craftsmanship.”
THIS was the group I had been looking for. While I had enjoyed the single-minded focus at the PADNUG group, I found the above ideas refreshing. As soon as I was settled (and learned my way around St. Louis!) I attended my first meet up, How Ruby is Making Me a Stronger C# Developer and a Better Man, presented by Darren Cauthon. The group itself was welcoming, and relaxed. Pizza and refreshments were on hand, and the monthly meet up is a Bring-Your-Own-Beer type of after-work affair.
The next month was a presentation by Jessica Kerr on Powerful Pattern Matching in F# / UX Techniques. Loved this too.
Since joining the STL ALT.NET group, I have been consistently impressed with the organization of the meet ups, and the energy with which Nicholas Cloud, the group’s principal and most visible organizer keeps the group moving. In keeping with my personal quest to expand my know-how, steal the hard-won education of others, and broaden my technological horizons, this was exactly the group I needed.
New Challenges to Face
It has been difficult for me to attend the group in the past few months, as a result of a heavy work travel schedule. I am hoping to get back in the swing of things in July now though, because I believe that participation in user groups (especially good ones) is of prime benefit to both the individual and the developer community. Even more, I believe that maximum benefit is obtained through consistent participation, and making a contribution. Even now, I am trying to find a topic on which I might present to the group. For me, the challenge in this is there is very little I might share with the experienced pros that they don’t already know. But I am going to try, BECAUSE of the challenge this represents.
Why YOU should Join a User Group
If you are a new and inexperienced programmer just starting to figure things out, or if you are an experienced pro who has never attended a user group or meetup, I strongly recommend you GET OFF YOUR ASS AND JOIN ONE. Yes, the initial social interaction thing is uncomfortable for most of us (we are, after all, geeks, right?), but there are few things which can bring a new vigor to your work more effectively than “getting involved” and “Giving back.”
And if you are in the Saint Louis area, I strongly recommend dropping into the STLALT.NET group. There will be pizza. You can bring beer. You WILL learn something. Plus, you probably have an education and professional experience I can steal while you are there.
If you are not in the St. Louis Area, or this specific group is not what you are looking for, you can most likely find one that IS what you seek HERE: Meetups in your area
If you are intrigued by the STLALT.NET group, you can find more info HERE: STL ALT.NET
You can follow the group on Twitter at : @stlaltdotnet
John on Google
SOPA and PIPA are only the beginning . . .
We all knew it would happen. Back in the '90s, Big media came late to the internet game. For most if its history, the internet has been (rightfully) held as a free exchange of ideas and information, with very little interference from government, at least in the Democratic West.
Now, in the last decade Big Media has taken notice. With the effective monetization of the web, Corporations have now moved into "our" space. The impact can be felt in the form of new regulations proposed, on a regular basis, with the aim of restricting the freedoms of the average internet user in a manner which benefits Big Media.
Prior to the evolution of profitable business models for on-line commerce, the big boys really had little interest in "our" space, and the profiteers in the US Senate and the House of Congress were less than interested in the internet. In the last ten years, however, that has begun to change, and in the last two, things have reached a critical mass. While big business was slow to catch on for the first decade of the internet, the sleeping giant is stirring . . .
Like turning an oil tanker
There is a familiar pattern to this. Each time a technology shift occurs in the content delivery space, large publishers and media companies cry about the threat of piracy, and that the sky is falling. Remember how Home Taping was going to kill music ("and it's illegal")?
How about when recordable CD's became publicly available? This was going to end the music industry.
With the advent of the internet, the game changed on media publishers, first and most visibly for the music industry. Napster made possible the ability to share your music collection far and wide. More importantly, you didn't have to buy an entire album to get the one song you wanted by an artist. While the wide-scale distribution of content-for-nothing via Napster and it's subsequent imitators in reality did represent copyright infringement and piracy, it also demonstrated a new business model for the internet era. Unfortunately, the record companies' and publisher's reaction was not to recognize which way the wind was blowing and adapt. Instead, they resorted to tried and true tactics (not really) of "lawyering up", using lawsuits, threats of lawsuits, and scare tactics in an attempt to restore the status quo. Instead of seizing the moment, instead of becoming early adopters and profiting handsomely, the Recording Industry Association of America (RIAA) reacted in a protectionist fashion, to its own detriment.
Come bite the Apple . . .
As it turned out, Apple recognized the potential of the new business model, and dragged the music industry kicking and screaming into the internet content delivery market. iTunes demonstrated that the majority will pay for legal downloadable content, provided an adequate, user-friendly mechanism to do so. Millions of paid downloads later, both Apple and subsequently Amazon have demonstrated that on-line delivery of paid-for digital music is not only viable, but highly profitable.
By the end of the first decade in the new millennium, delivery of high-definition streaming video has become not just a reality, but a fact of life. From humble beginnings in 2001, Netflix has amassed nearly 25 million subscribers, with an average growth of 2.4 million new subscribers per quarter through most of 2010 and 2011. While the company has since lost subscribers due to a series of marketing blunders, the demand for streaming video content delivery, and the willingness of the masses to pay for it are clear. At 25 million subscribers, Netflix currently has more subscribers than any single cable service provider including Comcast.
Think the internet is going to be the place where your video content comes from over the next decade?
Print media is lagging behind audio and video in achieving a profitable digital presence. But the decline in readership of "old-fashioned" paper magazines and newspapers, combined with the rise of digital readers such as the Kindle, Nook, and of course, the iPad show which way the wind is blowing here as well. In May of 2009, eMarketer reported that "nearly 20 million eReaders were expected to be in consumer hands" by the end of 2011, and that 12% of adults will have an eReader of some type or another. And of course, who can forget that on December 26th 2009, Amazon announced that for the first time, sales of Kindle books exceeded that of physical books.
Bring on the clowns . . .
Now, as the U.S. Congress attempts to pass some extraordinarily bad legislation in the form of SOPA ("Stop Online Piracy Act") and the US Senate does the same with PIPA ("ProtectIP" Act), we stand at a precipice. For the first time, American legislators are actively considering passing into law an Act or Acts which will radically change the internet as we know it forever. Either of these proposed pieces of legislation represent the first step in a process by which Corporate America will attempt to seize control of the internet in much the same way it did the radio broadcast market, and subsequently, the broadcast television spectrum.
As things sit right now, at 10:42 PM Central Time, a day of "protest" by major internet sites such as Wikipedia, Reddit, and others appears to have rattled the cage of our fearless leaders in D.C. Support for SOPA and PIPA has been evaporating throughout the day.
Don't worry. They'll be back.
Plus ça change, plus c'est la même chose (The more things change, the more they stay the same) . . .
With billions of dollars on the line, and the evaporation of historical distribution mechanisms for print, music, and visual media, the large powerhouses of the entertainment industry are not going to sit idly by while the free-as-in-beer internet replaces the money machine. SOPA and PIPA are likely only the opening salvos in a war by which the media companies do their ham-fisted worst to seize control of the internet, to the exclusion of the layman.
Can you imagine a day in which you might need to apply for a license to host a website? Or a day in which the dominance of a small group of mega-corporations on the web infrastructure is so great that there are no avenues for entry at the ground level?
Media markets for sale - contact your state representative for more information!
This may seem like paranoid thinking, when we examine the web as it is today. But take a look back. The internet is rapidly supplanting a multitude of industries which remain, to varying degrees, entrenched in an antiquated business model predicated on dominance through regulation. Television. Telecom. Audio recording, publishing and copyright. Print media. The players in these industries are not going to go quietly into the night. Instead they will, in the coming years, bring the full war chest to the table, starting with our elected officials (you know, the path of least resistance, right?).
It is our hope that the White House and the Congress will call on those who intend to stage this “blackout” to stop the hyperbole and PR stunts and engage in meaningful efforts to combat piracy.”
- (Former) Senator Chris Dodd, CEO of the Motion Picture Association of America, in response to planned protest of SOPA/PIPA
Imagine that! A former US Senator, now heading one of the largest lobbying groups in the country, is accusing the tech industry of engaging in "PR stunts" and hyperbole. I can only chuckle at the irony.
The thinking of big industry, and its attitude towards the rest of the internet community, could not be more effectively demonstrated than by this release (former) Senator Dodd from January 17th, the day before the "blackouts":
Chris Dodd Statement on "Blackout Day Protests"
If the connected community that is the world-wide-web does not succeed in preventing government encroachment and regulation, we face the very real threat of an internet which more closely resembles the "big three" of radio and television networks than the free information super-highway envisioned by its creators. SOPA and PIPA are bad, and they will likely die in the chambers of the Congress and the Senate. But SOPA and PIPA are only the beginning.
Congressional Support for SOPA/PIPA - A chart by Pro Publica showing who supports and opposes the measures. Interestingly, in the wake of today's (January 18th, 2012) internet "blackout" by a number of major internet sites (including Wikipedia), the balance on this chart has tipped dramatically since last night as legislators flee a "sinking ship".
SOPA is a red herring by Adam Curry - Interesting commentary makes the case that SOPA and PIPA are small-potatoes compared to changes being made to the Domain Naming system itself, and that the privacy aspect of the internet will be compromised forever.
Senate Copyright Bill Loses Key Supporters - Forbes Magazine, following the rush of former supporters (and several original co-sponsors) of the SOPA/PIPA legislation as they backpedal in an early election-season rush to please voters.