Project 2

Fine-Tuning Stats

Apologetic question: "Is the universe designed?"

Project 2 — Fine-Tuning Stats

“The most incomprehensible thing about the universe is that it is comprehensible.” — Albert Einstein

Chapter: 2 — Memory: Variables and Types Due: End of Week 2 Submit: A link to your code — an OnlineGDB project URL or a public GitHub repo URL — with fine_tuning.cpp as the main source file. See Appendix D for the full workflow. Allowed tools: Everything from Chapter 1 plus all five primitive types (int, double, bool, char, string), arithmetic, type conversion, and basic boolean expressions. Not yet allowed: if statements, loops, functions you define yourself, arrays.


The Setup

There’s a fact about the universe that nobody on any side of the religion-and-science conversation seriously disputes: a handful of physical constants are tuned within extraordinarily narrow ranges, and small changes to them give you a universe in which life as we know it cannot exist. The gravitational coupling constant. The cosmological constant. The mass ratio of the electron to the proton. The strong nuclear force. The level of the carbon-12 resonance state that allows stars to fuse carbon at all.

How tight are those ranges? Tighter than you’d guess. The cosmological constant, by some estimates, has to be tuned to roughly one part in 10^120. That’s a number with 120 zeros. There is no everyday analogy for it — every analogy your textbook authors tried to write here ended up sounding like cheating. It’s just an absurdly small number.

What people disagree about is what to make of those facts. Christians (and, for that matter, plenty of non-Christians) read it as evidence for design. Atheists tend to read it either as a multiverse selection effect or as a brute fact that needed no explanation. This program will not settle that argument. It will help you do the math.

Your job this week: build a calculator that takes the name of a physical constant, its measured value, the bounds of the life-permitting range, and a perturbation, and tells you whether life still works. By the end you’ll have a small, sturdy tool for thinking about a specific kind of question — one that any apologist working in 2026 needs to be able to do in their head, but that becomes much clearer when you can see the numbers in front of you.


Learning Targets

By completing this project, you will demonstrate that you can:

  • Use all five primitive types (int, double, bool, char, string) in one program.
  • Read multiple inputs of different types from the user.
  • Perform arithmetic that mixes ints and doubles without falling into the integer-division trap.
  • Convert between types explicitly when you need to.
  • Use boolean expressions to encode a yes/no judgement without if statements.
  • Produce formatted, multi-line, mixed-type output to the screen.

Normal Tier

Goal: A program that takes one physical constant’s data from the user and prints a formatted report about whether the measured value is in the life-permitting range, plus a few derived stats.

Required features

  1. Prompt the user for the following inputs, each into a variable of the correct type:

    • constant_name — a string (one word, e.g., gravitational_coupling).
    • measured_value — a double.
    • low_bound — a double (the lowest value of this constant compatible with life).
    • high_bound — a double (the highest value compatible with life).
    • perturbation_factor — a double (a small number near 1.0, e.g., 1.001 for a 0.1% perturbation).
  2. Compute the following derived values:

    • range = high_bound - low_bound
    • margin = (measured_value - low_bound) / range (a number between 0 and 1 if the measurement is in range — note this is a double / double ratio; be careful not to fall into the integer-division trap if you accidentally use ints).
    • perturbed_value = measured_value * perturbation_factor
    • is_life_permitting = (measured_value >= low_bound) && (measured_value <= high_bound)
  3. Print a formatted report to the console. The report must:

    • Be at least 8 lines long.
    • Be visually structured with a clear top/bottom border (carry forward the card aesthetic from Project 1 if you like).
    • Display every variable from steps 1 and 2 with a clear label.
    • Print the bool is_life_permitting as true/false (use boolalpha), not 1/0.
  4. Compiles cleanly with -Wall -Wextra enabled in OnlineGDB compiler settings (or g++ -Wall -Wextra if you build locally). No warnings, no errors.

  5. No integer-division bugs. If you input measured = 5.0, low = 1.0, high = 11.0, your margin should print 0.4 — not 0. The grader will check this.

Example of acceptable output

User types gravitational_coupling 5.9e-39 1.0e-40 1.0e-38 1.001:

+-----------------------------------------------+
|             FINE-TUNING REPORT                |
+-----------------------------------------------+
  Constant:         gravitational_coupling
  Measured value:   5.9e-39
  Range:            [1e-40, 1e-38]
  Range width:      9.9e-39
  Margin in range:  0.585859
  Perturbation (×): 1.001
  Perturbed value:  5.9059e-39
  Life-permitting:  true
+-----------------------------------------------+

Grading rubric — Normal (out of 100)

CriterionPoints
Compiles cleanly with -Wall -Wextra and no warnings10
Reads constant_name as a string5
Reads four numeric inputs as double10
Correctly computes range and margin15
Correctly computes perturbed_value10
Correctly computes is_life_permitting as a bool10
No integer-division bugs in margin10
Output is at least 8 lines, with top and bottom borders10
Output labels every value clearly10
bool prints as true/false, not 1/05
OnlineGDB/GitHub link + reflection comment block5

Medium Tier (+up to 25% extra credit)

Layer the following on top of Normal. Implement one for partial credit, all three for full Medium.

M1. Perturbation percentage instead of factor

Replace the “perturbation factor” input with a “perturbation percentage” input. The user types a percent (like 0.1 for “shift by 0.1%”), and your program computes:

perturbed_value = measured_value * (1 + percent / 100.0)

Watch out: if you do percent / 100, you might trigger integer division. Decide on a type for percent and stick with it. Mix integer and floating-point inputs only with explicit casts.

Print both the perturbed-value and a “still life-permitting after perturbation?” boolean.

M2. Side-by-side before/after

After computing the perturbed value, print a side-by-side comparison. Same labels, two columns:

                     Measured        Perturbed
Value:               5.9e-39         5.9059e-39
In range:            true            true
Margin in range:     0.5859          0.5865

Use "\t" (or careful spaces) to align the columns. Don’t worry if very long values throw off the alignment — fixed-width inputs are fine.

M3. The “constant class” tag

Add a char input for the class of the constant:

  • 'G' — gravitational
  • 'C' — cosmological
  • 'E' — electromagnetic / electroweak
  • 'N' — nuclear
  • 'O' — other

Display the full class name on the report (e.g., “Class: gravitational”). Since you don’t have if statements yet, you’ll need to either (a) print all five labels next to a 0-or-1 boolean each — visually noisy, but it works and is the recommended path — or (b) if you’re feeling clever, see if you can find another no-if path. Be warned: it gets ugly fast. The multiply-by-boolean trick works for numbers but not directly for strings, so any string-label workaround will involve gymnastics. The cleaner solution comes next week.

Coach’s Note — M3 is a forced reminder that conditionals are about to make your life easier. Don’t try to be too clever — the point is to feel the pain of writing dispatch logic with no if available. Next week the relief will land harder because of it.


Hard Tier (+up to 25% additional extra credit)

The Hard tier asks you to combine the new skills and foreshadow Chapter 3 (booleans-and-arithmetic) plus Chapter 4 (loops). You may pick any one Hard feature.

H1. Class-specific scaling without conditionals

Take M3’s char class_char. For each class, the “tolerance” of the life-permitting range is different (you’re going to make these up — that’s fine for a Week 2 project). For example:

  • 'G' → very narrow tolerance (life is sensitive to gravitational changes)
  • 'C' → astonishingly narrow tolerance (cosmological constant)
  • 'E' → moderate
  • 'N' → narrow
  • 'O' → wide

Use boolean math (no if) to compute a double class_scaling_factor based on class_char. Hint: (class_char == 'G') * 0.001 + (class_char == 'C') * 0.0000001 + .... Exactly one of those terms is non-zero, because exactly one of the equality checks is true.

Then compute a “class-adjusted margin”: margin / class_scaling_factor. Larger means more astonishing.

This is exactly the boolean-as-arithmetic technique from §2.7. Get it working. Next week you’ll do the same thing with proper if statements and laugh at how much cleaner it is.

H2. Three constants in one report

Ask the user to enter data for three constants. (You don’t have arrays yet, so use three sets of variables: name1, value1, low1, high1, …, name2, …, name3, …) Compute the same derived stats for all three. Print a comparative report:

Constant                  Measured       Margin     Life-permitting
gravitational_coupling    5.9e-39        0.586      true
cosmological_constant     1.1056e-52     0.234      true
electron_proton_ratio     0.00054        0.412      true

This is your first taste of “I really wish I had a way to handle a collection of similar things.” That tool is called an array, and it shows up in Chapter 6. For now, brute-force it. The brute force is the rep.

H3. The flex move

Find one feature of C++ that we didn’t cover this chapter and use it in your program. Document it in your reflection comment block per the same rules as Project 1’s H4.

Strong candidates:

  • std::setw and std::setprecision from <iomanip> for clean number formatting.
  • std::pow(base, exponent) from <cmath> for exponential math.
  • std::abs(x) from <cmath> for absolute value (useful for “how far is measured from the center of the range?”).
  • getline(cin, line) so the user can type multi-word constant names.

Pick one. Make it earn its place in your program.


Submission

Submit one URL via the course portal:

  • OnlineGDB project link (recommended for Coding 1 and Coding 2). Create your project at onlinegdb.com, set compiler flags to -Wall -Wextra in the project settings, build your solution, and share the link. See Appendix D for the full workflow.
  • GitHub repo link (optional). If you’ve set up local development on your own, push the source to a public repo and submit that URL. You’re responsible for making sure the code compiles when the grader checks it out.

What the linked project must contain

  1. The main source filefine_tuning.cpp — containing your full solution.
  2. A reflection comment block at the very top of that file:
/*
 * Tier targeted:    Normal / Medium / Hard
 * Features done:    list each feature you completed
 * What I learned:   one short paragraph (no bullets)
 * What I'd change:  one sentence
 * AI usage:         where and how, if any. Be honest.
 */
  1. The program left in a “demonstrable” state — when the grader presses Run, the features for your targeted tier should be exercised. Hard-code inputs at the top of main() (or pre-fill OnlineGDB’s Stdin panel) so the grader doesn’t have to guess what to type.

That’s it. No separate demo.txt. No screenshots. The instructor will open your link, read the comment block, run the program, and grade against the rubric.

Coach’s Note — Coding 1 and Coding 2 focus on writing code, not managing development environments. If something behaves oddly, you and the grader are looking at the exact same browser-hosted environment — there are no “works on my machine” defenses by design. Coding 3 will introduce a local toolchain properly.

Hints (Read These If You’re Stuck)

  • “My margin is always 0.” Integer division. One of your inputs is being read as an int, or you’re dividing two ints. Promote at least one to double.
  • 5.9e-39 doesn’t compile.” Make sure the variable you’re reading into is double, not int. Scientific notation only works for floating-point.
  • “My bool prints as 1, not true.” Add cout << boolalpha; once near the top of main().
  • “The compiler complains about static_cast.” You used <int> instead of <double> (or vice versa). The cast target type matters.
  • “My alignment is off.” That’s normal for variable-length numeric output. For Project 2, perfect alignment isn’t required; intentional structure is.
  • “How long should this take me?” Normal: 1–2 hours if you did the Reps. Medium: 2–3 hours. Hard: 3–5 hours.

What Mastery Looks Like (Beyond the Rubric)

A great Project 2 has the integer-division trap absolutely killed dead. You should be able to take any combination of int and double inputs and confidently know what types every intermediate calculation is producing, and where you cast.

A great Project 2 is honest about its inputs. Real physical constants come in specific units (meters, kilograms, seconds, or dimensionless ratios). If you label a variable gravitational_coupling, it should hold an actual gravitational coupling value, not a placeholder. The grader can tell whether you looked up real numbers.

A great Project 2 doesn’t oversell what it is. The program is a calculator, not an argument. The report doesn’t conclude “therefore, God.” It reports numbers. The numbers, made legible, can speak for themselves to readers who are willing to think about them.


When You’re Done

  1. Read your own fine_tuning.cpp out loud. Slowly. Listen to the data types in each line.
  2. Run it three times with three different inputs: one clearly in range, one clearly above, one clearly below.
  3. Update your README.txt. (Be honest about tier.)
  4. Submit.
  5. Read Chapter 3. We start making programs decide.

Coach’s Note — Project 2 is the project where students start sorting themselves. The ones who took Chapter 2’s reps seriously will breeze through Normal in an evening and have time to push into Medium or Hard. The ones who skimmed Chapter 2 will get punched by the integer-division trap somewhere in their margin calculation, lose two hours debugging, and submit Normal with one feature broken. Don’t be the second group. If you haven’t done the Reps, close this file, go do them, then come back.

See you on Monday.