Assignment 2#
Due: Wednesday Sep 9th at 11:59 pm ET
The goal of this assignment is to work with Bash, git, GitHub, and Pixi. You will set up the repository you will use for all of your assignments this semester, and inside it build a small, fully reproducible geospatial tool. Along the way you will practice the everyday workflow you will use for the rest of the course: initializing a project, managing its environment with Pixi, and making frequent, meaningful commits to GitHub.
The tool itself is deliberately small: a command-line program that computes the great-circle distance between two geographic coordinates. You will grow it one step at a time, and by the end anyone will be able to clone your repository, run a single command, and reproduce your results exactly, environment and all.
Important
Throughout this assignment, stage your files explicitly by name (for example git add distance.py). Do not use git add . As discussed in the Git lecture, git add . bundles unrelated changes together and makes it easy to accidentally commit generated files or secrets. Run git status before every commit and add only the files that belong in that commit.
Part 1: Create Your Assignments Repository (20 pts)#
You will submit every assignment this semester to a single GitHub repository. Create it on GitHub first, then bring it down to your computer with git clone.
On GitHub, create a new private repository called
geog313-assignments. (Call it exactly like that. Do not vary the spelling, capitalization, or punctuation.) Initialize it with a README so there is something to clone.Still on GitHub, go to “Settings” → “Collaborators” → “Add People” and add
hamedalemoanddwgodwinas collaborators.On your local machine, clone the repository.
Edit
README.mdso it contains your name and one sentence describing what the repository is for. Stage it explicitly, commit, and push to GitHub.
Part 2: A Reproducible Geospatial Tool with Pixi (80 pts)#
Everything for this assignment lives in a new directory named assignment-2/ inside your geog313-assignments repository. Inside it you will create a Pixi project and build it up in small steps, committing after each step. Your grade is partially based on your commit history: we expect to see at least six separate commits, each with a clear, informative message, built up as you go (not one giant commit at the end).
2.1 Initialize the Pixi project#
From the root of your
geog313-assignmentsrepository, create the assignment folder and initialize Pixi inside it:$ pixi init assignment-2 $ cd assignment-2
Run
git statusand confirm that the.pixi/folder does not appear as something to be tracked.Add Python as a dependency to this project.
Open
pixi.tomland edit theplatformsline so the project supports the operating systems used in this class:platforms = ["osx-arm64", "osx-64", "linux-64"]
Make a commit with just the project scaffolding so far.
Note
The files you commit for a Pixi project are pixi.toml and, once it exists, pixi.lock. You should never commit the .pixi/ folder — it is large and is fully reproducible from the manifest and lock file.
2.2 Write the distance function#
The haversine formula computes the great circle distance between two points on a sphere given their latitudes and longitudes. For this first step you only need Python’s built-in math module.
Inside
assignment-2/, create a file calleddistance.py. Write a functionhaversine(lat1, lon1, lat2, lon2)that returns the distance in kilometers (use an Earth radius of 6371 km). Then, in aif __name__ == "__main__":block, call it for two real locations of your choice — for example your hometown and Clark University (Worcester, MA is about42.2506, -71.8231) — and print the result:from math import radians, sin, cos, asin, sqrt def haversine(lat1, lon1, lat2, lon2): # convert degrees to radians, apply the haversine formula, # and return the distance in kilometers (R = 6371 km) ... if __name__ == "__main__": d = haversine(42.2506, -71.8231, 40.7128, -74.0060) # Worcester -> New York City print(f"Distance: {d:.1f} km")
Run it inside your Pixi environment to confirm it works.
Commit
distance.py(stage it explicitly).
2.3 Add a package and review the lock file#
A single distance is not very interesting. Let’s expand your script to hold a list of three locations (name, latitude, longitude) and print a table of the distances between them. To format that table nicely, add the tabulate package from conda-forge:
Add
tabulateas a dependency to your pixi environment.Run
git status. You will see that bothpixi.toml(your intent) andpixi.lock(the exact resolved versions) have changed.Commit
pixi.toml,pixi.lock(stage it explicitly).Update
distance.pyto build a table of pairwise distances between your locations and print it withtabulate.Commit
distance.py(stage it explicitly).
Why commit the lock file?
pixi.toml records what you asked for; pixi.lock records what you actually got, down to every transitive dependency, for every platform. Committing the lock file is what makes your project reproducible for anyone else. Get in the habit now: whenever pixi add changes the lock file, commit pixi.toml and pixi.lock together.
2.4 Build out the tool, one commit at a time#
Now add features to distance.py one at a time, committing after each feature. Add the following, as separate commits:
More locations — grow your list to at least five places that mean something to you.
A “nearest neighbor” helper — a function that, given one location, reports which other location in your list is closest (and how far).
Miles as well as kilometers — let the tool report distances in both units (1 km ≈ 0.621371 miles).
2.5 Add a Pixi task#
Make your tool runnable with a single, memorable command by defining a Pixi task:
$ pixi task add distances "python distance.py"
$ pixi run distances
This adds a [tasks] entry to pixi.toml. Commit that change.
2.6 Push and confirm#
Push your work to GitHub. From now on, push after each new commit so your GitHub history reflects your work as it progresses.
On GitHub, open the
assignment-2/folder and confirm thatpixi.toml,pixi.lock,distance.py, and.gitignoreare all there — and that.pixi/is not.
2.7 Prove it is reproducible#
This is the payoff. Simulate a collaborator (or a grader) picking up your work on a clean machine:
Move to a different directory (for example your home directory) and clone a fresh copy of the whole repository under a new name, then run the tool:
$ cd ~ $ git clone git@github.com:<your-username>/geog313-assignments.git geog313-clone $ cd geog313-clone/assignment-2 $ pixi install $ pixi run distances
Confirm that your tool runs correctly using only the files committed to GitHub. If it does not, something your project needs was not committed — fix it, commit, and push.
[Optional] Part 3. Geodesic Distance#
This section is optional, and if you successfully complete it you will get extra 10 points.
Add the geopy package and compare your spherical haversine distance to geopy.distance.geodesic, which uses the WGS84 ellipsoid. Print both distances for one pair of points and note how much they differ. We will return to why the shape of the Earth matters when we reach coordinate reference systems later in the course.
Remember to commit the manifest and lock file changes.
Deliverables#
Everything is submitted to your private geog313-assignments repository (with hamedalemo and dwgodwin added as collaborators):
A root
README.mdwith your name and a description of the repository.An
assignment-2/directory containingdistance.py,pixi.toml,pixi.lock, and.gitignorewith a commit history showing at least six meaningful, separate commits for the tool.