Project 7

Evidence Inventory

Apologetic question: "Did the Resurrection happen?"

Project 7 — Evidence Inventory

“For I delivered to you as of first importance what I also received: that Christ died for our sins in accordance with the Scriptures, that he was buried, that he was raised on the third day in accordance with the Scriptures, and that he appeared…” — 1 Corinthians 15:3–5

(One of the earliest dated creeds in the New Testament — by scholarly consensus, formulated within roughly five years of the events. Use that as one piece of evidence in your inventory.)

Chapter: 7 — Grouping Memory: Structs Due: End of Week 7 Submit: A link to your code — an OnlineGDB project URL or a public GitHub repo URL — with evidence.cpp as the main source file. See Appendix D for the full workflow. Allowed tools: Everything through Chapter 7 — types, conditionals, loops, functions, arrays, strings, structs. Not yet allowed: Classes, dynamic memory.


The Setup

Christian historical apologetics — especially around the central claim of the Resurrection — has, since at least the 1970s, made heavy use of what Gary Habermas calls the “minimal facts” approach. The idea: rather than relying on the inerrancy of the Gospels (which is its own argument), identify a small set of facts that the overwhelming majority of historians of all persuasions accept as historically credible, and then ask what best explains them.

The standard set varies a little by author, but the canonical list includes things like:

  1. Jesus’ death by crucifixion. Accepted by essentially every historian.
  2. The empty tomb tradition. Disputed by some, but the tradition itself (early, multiply-attested) is broadly accepted.
  3. The post-mortem appearances. That the disciples reported having seen the risen Jesus is broadly accepted (whether the appearances were real is what’s debated).
  4. The early Christian creed of 1 Corinthians 15:3–7. Dated by most scholars to within ~5 years of the events — strikingly early.
  5. The transformation and martyrdom of the disciples. People who could have walked away from the claim chose not to, often at great personal cost.
  6. The conversion of Paul. A persecutor of the church becomes its most active missionary, on the strength of a claimed encounter.
  7. The conversion of James. Jesus’ brother, who was a skeptic during the ministry, becomes a leader of the Jerusalem church.

You can find longer lists. Wright’s three-volume Christian Origins and the Question of God is the heavyweight academic case. McGrew’s Bayesian analysis pushes the formal probability work. Habermas’s The Risen Jesus and Future Hope is the accessible summary. None of these are required reading for this project — but if any of them are in your library or your university’s library, browse them while you build this. The data shape will feel familiar.

This project: build an inventory of evidence. Each piece is a struct. Add, remove, list, search, filter, weigh. By the end you will have, in code, a small structured representation of the case you might one day be asked to make over a coffee.

Coach’s Note (confessional Lutheran framing) — The minimal-facts approach is one mode of intellectual engagement, not the foundation of Christian faith. In the Lutheran tradition (Augsburg Confession V), saving faith is created and sustained by the Word and the Sacraments — not by a sufficient stack of historical probabilities. The evidence is real, the data is striking, and you should know it. But the inventory in this project is a tool for the conversation, not a proof that converts. Sources of the same data: Habermas (Evangelical), Wright (Anglican), Plantinga (Reformed). For an explicitly Lutheran take on apologetics, see John Warwick Montgomery’s History, Law, and Christianity or Rod Rosenbladt’s lectures.


Learning Targets

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

  • Define a non-trivial struct with multiple field types.
  • Maintain an array of structs with a count variable.
  • Pass structs to functions by value and by reference (and const &).
  • Implement add, remove, search, filter operations on a struct array.
  • Compute aggregate statistics over a struct array.
  • Use a char field for category-style data.

Normal Tier

Goal: A menu-driven inventory of up to 25 pieces of evidence, each a struct.

Required features

  1. Define the Evidence struct with at least these fields:

    struct Evidence {
        string claim;            // a short statement of the evidence
        string source;           // who/where attests it
        string type;             // e.g., "textual", "historical", "archaeological", "experiential"
        int strength_rating;     // 1-10
        int year;                // earliest credibly attested year
    };
  2. Seed data: Pre-populate the inventory with at least 6 real pieces of evidence. Use the canonical Resurrection minimal-facts list above (or another carefully-chosen historical claim — apologetics for the historical reliability of the Gospels, for the existence of God via the moral argument, for the early dating of NT documents — any one would work). The data must be real: don’t make up sources or invent claims. The grader will check.

  3. Menu loop with these options:

    • 1. Add a piece of evidence — prompt for all fields. Reject if strength_rating is outside 1–10. Reject if the inventory is full.
    • 2. Remove by claim — prompt for the claim string, find it (case-insensitive), shift others down.
    • 3. List all — prints a formatted table of all current entries (with strength_rating and year).
    • 4. Find by claim — case-insensitive search.
    • 5. Exit
  4. Functions, not inline code. Each operation lives in a named function (add_evidence, remove_evidence, list_evidence, find_evidence). main is the menu loop.

  5. Compiles cleanly with -Wall -Wextra enabled. No warnings.

Example table output

=== Evidence Inventory (6 entries) ===

#  Claim                                    Source                  Type            Strength  Year
1  Jesus' death by crucifixion              Multiple Gospels, Tacitus historical      10        AD 30
2  Empty tomb tradition                     All four Gospels        textual         8         AD 35
3  Post-mortem appearance tradition         1 Cor 15:3-7 creed      textual         9         AD 35
4  Conversion of Paul                       Acts, Pauline epistles  historical      10        AD 35
5  Conversion of James                      1 Cor 15:7, Acts        historical      8         AD 35
6  Martyrdom of multiple eyewitnesses       Patristic sources       historical      7         AD 60

Aim for well-formatted output; column alignment is appreciated but not required. Tabs and a consistent field order are enough. (Pixel-perfect alignment usually means reaching for <iomanip>::setw, which we’ll cover later — for now, readable beats ruler-straight.)

Grading rubric — Normal (out of 100)

CriterionPoints
Compiles cleanly with -Wall -Wextra10
Evidence struct correctly declared with 5+ fields10
Seed data: at least 6 real entries, sources verifiable15
add_evidence validates strength_rating (1-10)10
remove_evidence works with shift-down10
list_evidence prints a formatted table10
find_evidence case-insensitive10
Functions take structs by value or const & appropriately10
main is menu + dispatch — no business logic10
OnlineGDB/GitHub link + reflection comment block5

Medium Tier (+up to 25% extra credit)

M1. Freshness and review

Add a freshness field (int, starts at 100) to the Evidence struct. Add a menu option Review evidence by claim. Reviewing decrements freshness by, say, 10. When freshness reaches 0, the evidence is automatically removed from the inventory and a message printed:

[The evidence "X" has not been re-examined recently and has been moved to a needs-attention queue.]

(For Medium tier you don’t actually need a separate queue — just remove it and print the message. The “needs attention” framing is for the user.)

This is the analog to a Resurrection-tradition lecture: scholarship moves, sources get reconsidered, and any piece of evidence benefits from being re-checked periodically.

M2. Case strength total

Add a menu option Show case strength. Compute the sum of strength_rating across all current entries. Print:

Case strength: 52 (across 7 pieces of evidence; average 7.4)

Use a function int total_strength(const Evidence[], int count) and a function double average_strength(const Evidence[], int count). No business logic in main — push computation into functions.

M3. Filter by type

Add a menu option Filter by type. Prompts for a type string (textual, historical, etc.) and prints all entries of that type. Show the case-strength subtotal for that type.


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

The Hard tier foreshadows polymorphism with category-specific behaviors.

H1. Category char and dispatch

Add a char category field to the Evidence struct:

  • 'T' — textual
  • 'H' — historical
  • 'A' — archaeological
  • 'E' — experiential

Implement category-specific review functions:

  • void review_textual(Evidence& e) — decrements freshness by 5 (textual evidence ages slowly).
  • void review_historical(Evidence& e) — decrements by 10.
  • void review_archaeological(Evidence& e) — toggles a bool currently_disputed field. (Add this field to the struct too.)
  • void review_experiential(Evidence& e) — decrements strength_rating by 1 if it’s above 3, otherwise leaves it alone. (Experiential evidence is the most volatile.)

Then write void review_evidence(Evidence& e) that dispatches based on category:

void review_evidence(Evidence& e) {
    switch (e.category) {
        case 'T': review_textual(e); break;
        case 'H': review_historical(e); break;
        case 'A': review_archaeological(e); break;
        case 'E': review_experiential(e); break;
        default: break;
    }
}

Coach’s Note — This switch-based dispatch is what polymorphism replaces. Hold this code in your head — in two weeks (Chapter 12) you’ll write the same logic without any switch, using virtual methods on a class hierarchy. The compiler will dispatch for you. This is the foreshadowing the project arc keeps mentioning.

H2. Save and load

Use file I/O — <fstream> — to save the inventory to a text file and reload it next session. Each line of the file is one piece of evidence, with fields separated by |:

Jesus' death by crucifixion|Tacitus, Annals 15.44|historical|10|30|H
Empty tomb tradition|Mark 16; Matthew 28; Luke 24; John 20|textual|8|35|T

Implement:

  • void save_inventory(string filename, const Evidence[], int count) — writes the file.
  • int load_inventory(string filename, Evidence[], int max) — reads the file, returns the count loaded.

getline with a custom delimiter character is the trick. Look it up.

Coach’s Note — File I/O isn’t formally covered in this course (it’s a Chapter 12-equivalent topic in many curricula). Adding it here is genuinely a stretch — that’s why it’s Hard. If it takes you longer than 4 hours, ship without it.

H3. The flex move

Find one C++ feature not covered this chapter. Strong candidates:

  • std::vector<Evidence> — dynamic array.
  • Operator overloading: define bool operator<(const Evidence& a, const Evidence& b) so you can use std::sort with built-in comparison.
  • A static counter inside a function (e.g., total reviews performed across the session).

Document per Project 1 H4 rules.


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 fileevidence.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

  • “My struct is getting cluttered.” Six fields is fine. Eight is the upper end of comfortable. If you’re at twelve, you may be modeling too much in one type — break it up.
  • “Comparing strings in find_evidence is annoying.” Reuse your case-insensitive helper from Project 6.
  • “Removing from the middle keeps a hole.” Shift down: for (int j = i; j < count - 1; j++) { inv[j] = inv[j + 1]; } then count--;. The whole struct is copied per iteration; no parallel-array drift possible.
  • “My case-strength computation is wrong.” Make sure you’re iterating only up to count, not to the array’s full size. Empty slots may have garbage values.
  • “I want to use a class instead of a struct.” Hold off until Chapter 9. The point of this week is to feel structs working — and to feel the absence of methods. Project 9 introduces classes, and you can revisit then.
  • “How long should this take me?” Normal: 3–5 hours. Medium: 5–9 hours. Hard: 8–14 hours (file I/O is the time sink).

What Mastery Looks Like

A great Project 7 has honest data. Every piece of evidence corresponds to something a real scholar has actually argued. Sources are real (Tacitus is real; “TacitusBook15.44” is a real citation; “Tacitus said the disciples saw Jesus” is not real, because he didn’t say that). Dates are real (the 1 Corinthians 15 creed really does date to ~AD 35 by most scholars; you didn’t make that up).

A great Project 7 has bundled data. Removing a piece of evidence doesn’t risk leaving its source or strength dangling somewhere. The struct does the bundling. The functions operate on bundled data.

A great Project 7 has short, sharp functions. Each one does a single thing. total_strength returns an int. review_textual modifies an Evidence&. find_by_claim returns an int. Combined in main, they form a small, readable database engine.

A great Project 7 is something you might actually use. Run it. Look at your inventory. Could you imagine showing this to a friend who asked the question? If so — and if the data is real — you’ve done something genuinely apologetic. Not by winning an argument. By being able to point at the data.


When You’re Done

  1. Read your evidence.cpp aloud. Each function does one thing. The struct’s fields are clearly named.
  2. Run a stress test: add 5 entries, remove 1, list, filter by type, review. Anything break?
  3. Update README. Verify your sources.
  4. Submit.
  5. Prepare for the midterm. Chapter 8 / Project 8 is next — a 75-minute live exam over everything in Chapters 1–7.

Coach’s Note — This is the last project before the midterm. If you can ship a clean Normal here, you have all the procedural C++ chops the midterm tests. If Medium and Hard worked too, you’ll cruise. Use this weekend to consolidate. Read your code from Projects 1–7 side by side. The patterns repeat. By the time you sit down to the midterm, the patterns should feel familiar.

See you in the exam room.