CS 3180 Mobile Application Development

πŸ† Midterm Blitz

CS 3180 Week 9 β€” Competition Review

Midterm Exam is Friday!

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Competition Rules

  1. Teams of 3-4 β€” form your group now
  2. Write answers privately before revealing
  3. Show answers simultaneously on instructor's mark
  4. No devices during questions (except during coding rounds)
  5. Points tracked on the board β€” winning team gets bragging rights
Round Questions Points Each
Round 1: Quick Fire 10 MC 1 pt
Round 2: Short Answer Showdown 5 SA 2 pts
Round 3: Code Challenge 3 coding 3 pts
Total possible 29 pts
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Round 1

⚑ Quick Fire

Multiple Choice β€” 1 point each

30 seconds per question. Write your answer, then reveal!

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q1 Β· Kotlin Basics 1 pt

Which of the following is an immutable variable declaration in Kotlin?

  • A) var name = "Alice"
  • B) val name = "Alice"
  • C) const name = "Alice"
  • D) let name = "Alice"
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q1 Answer βœ…

B β€” val name = "Alice"
  • val = immutable (read-only), cannot be reassigned
  • var = mutable, can be reassigned
  • const exists in Kotlin but only for compile-time constants at top level / companion objects
  • let is a scope function in Kotlin, not a declaration keyword
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q2 Β· Android Lifecycle 1 pt

What happens when you rotate an Android device by default?

  • A) The app crashes
  • B) Nothing changes
  • C) The Activity is destroyed and recreated
  • D) Only the UI is refreshed
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q2 Answer βœ…

C β€” The Activity is destroyed and recreated
  • Device rotation = configuration change
  • Android destroys and recreates the Activity by default
  • This is why state stored in a ViewModel survives rotation β€” it outlives the Activity
  • Without ViewModel, you lose all non-persisted state on rotation
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q3 Β· Compose Lists 1 pt

Which composable is best for displaying a large scrollable list efficiently?

  • A) Column with Modifier.verticalScroll()
  • B) LazyColumn
  • C) Row with Modifier.horizontalScroll()
  • D) Box
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q3 Answer βœ…

B β€” LazyColumn
  • LazyColumn only composes visible items (lazy evaluation)
  • Column + verticalScroll composes all items at once β€” bad for 1000+ items
  • Memory efficient: off-screen items are discarded and recomposed when needed
  • Think of it like RecyclerView, but declarative
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q4 Β· State Management 1 pt

What is the purpose of remember in Jetpack Compose?

  • A) To remember user credentials
  • B) To cache images
  • C) To preserve state across recompositions
  • D) To log debug information
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q4 Answer βœ…

C β€” Preserve state across recompositions
  • Without remember: variable resets to initial value on every recomposition
  • With remember: value survives recompositions within the same composition
  • Does NOT survive configuration changes (rotation) β€” use rememberSaveable or ViewModel for that
  • Usually paired with mutableStateOf: var count by remember { mutableStateOf(0) }
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q5 Β· Resources & Localization 1 pt

Which file would you modify to add a Spanish translation for a string resource?

  • A) res/values/strings.xml
  • B) res/values-es/strings.xml
  • C) res/spanish/strings.xml
  • D) res/locale-es/strings.xml
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q5 Answer βœ…

B β€” res/values-es/strings.xml
  • Format: res/values-[language-code]/strings.xml
  • Language codes follow BCP 47: es = Spanish, fr = French, zh = Chinese
  • Android automatically picks the right file based on device locale settings
  • Fallback: if no matching locale found, uses res/values/strings.xml
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q6 Β· Architecture 1 pt

What is the primary purpose of a ViewModel in Android architecture?

  • A) To render the UI
  • B) To survive configuration changes and manage UI-related data
  • C) To handle database operations
  • D) To manage app permissions
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q6 Answer βœ…

B β€” Survive config changes and manage UI-related data
  • ViewModel is tied to a lifecycle scope, not an Activity instance
  • Survives rotation, language changes, and other config changes
  • Holds UI state exposed as StateFlow or LiveData
  • Does not directly handle DB β€” delegates to a Repository
Activity/Composable β†’ ViewModel β†’ Repository β†’ Room/API
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q7 Β· Kotlin Collections 1 pt

Which Kotlin function would you use to filter a list to only even numbers?

  • A) map
  • B) filter
  • C) reduce
  • D) forEach
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q7 Answer βœ…

B β€” filter
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evens = numbers.filter { it % 2 == 0 }
// Result: [2, 4, 6]
Function Purpose Returns
map Transform each element New list, same size
filter Keep elements matching predicate New list, smaller or equal
reduce Combine all elements into one Single value
forEach Iterate (side effects) Unit
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q8 Β· Null Safety 1 pt

What does the ?: operator do in Kotlin?

  • A) Checks for equality
  • B) Provides a default value if the left side is null (Elvis operator)
  • C) Performs safe navigation
  • D) Casts types safely
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q8 Answer βœ…

B β€” Elvis operator: default value if null
val name: String? = null

// Without Elvis:
val display = if (name != null) name else "Anonymous"

// With Elvis:
val display = name ?: "Anonymous"
  • ?. = safe call (returns null if left is null)
  • ?: = Elvis (returns right side if left is null)
  • !! = not-null assertion (throws if null β€” avoid!)
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q9 Β· Material Design 1 pt

In Material Design 3, which color role is typically used for primary action buttons?

  • A) onPrimary
  • B) primary
  • C) secondary
  • D) tertiary
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q9 Answer βœ…

B β€” primary

Material Design 3 color roles:

Role Use
primary Most important actions and components
onPrimary Content (text/icons) displayed on primary
secondary Less prominent actions
surface Background of cards, sheets
error Error states
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q10 Β· Navigation 1 pt

What is the correct way to navigate to a new screen in Jetpack Compose Navigation?

  • A) navController.navigateTo("screen")
  • B) navController.navigate("screen")
  • C) Navigation.goTo("screen")
  • D) Navigator.push("screen")
⏱ 30 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q10 Answer βœ…

B β€” navController.navigate("screen")
// String-based (basic):
navController.navigate("profile")

// Type-safe (modern):
navController.navigate(Routes.Profile(userId = 42))

// Go back:
navController.popBackStack()
navController.navigateUp()
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

πŸ“Š Round 1 Scoreboard

Tally up your team's points!

Max: 10 points

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Round 2

πŸ’‘ Short Answer Showdown

2 points each β€” Team discussion allowed!

60 seconds to discuss, then one team member answers aloud

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q11 Β· var vs val 2 pts

Explain the difference between var and val in Kotlin.

Bonus: Give one real example of when you'd use each in an Android app.

⏱ 60 seconds β€” discuss with your team
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q11 Answer βœ…

val β€” immutable, cannot be reassigned after initialization

val maxScore = 100         // never changes
val appName = "MyApp"      // constant

var β€” mutable, can be reassigned

var count by remember { mutableStateOf(0) }   // changes on button tap
var isLoggedIn = false                          // changes on login

Rule of thumb: Start with val. Only use var when the value must change.

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q12 Β· State Hoisting 2 pts

What is state hoisting in Jetpack Compose? Why is it important?

⏱ 60 seconds β€” discuss with your team
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q12 Answer βœ…

State hoisting = moving state UP from a composable to its caller

// Stateful (state inside β€” not hoisted):
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) { Text("$count") }
}

// Stateless (state hoisted β€” caller controls it):
@Composable
fun Counter(count: Int, onIncrement: () -> Unit) {
    Button(onClick = onIncrement) { Text("$count") }
}

Why it matters: Reusable Β· Testable Β· Single source of truth

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q13 Β· Android Lifecycle 2 pts

Name four Android Activity lifecycle states and explain when an activity transitions between two of them.

⏱ 60 seconds β€” discuss with your team
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q13 Answer βœ…

onCreate() β†’ onStart() β†’ onResume() β†’ [Running]
                                           ↓
                                       onPause()
                                           ↓
                                       onStop()
                                           ↓
                                       onDestroy()
Transition Trigger
Started β†’ Resumed App comes to foreground
Resumed β†’ Paused Dialog/notification covers app
Paused β†’ Stopped App no longer visible
Stopped β†’ Destroyed Rotation, finish(), or system kills it
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q14 Β· Null Safety 2 pts

What is null safety in Kotlin? How does it prevent crashes compared to Java?

⏱ 60 seconds β€” discuss with your team
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q14 Answer βœ…

Null safety = Kotlin's type system distinguishes nullable from non-nullable types at compile time

var name: String = "Alice"   // Cannot be null β€” compiler enforces
var name: String? = null     // Can be null β€” must handle it

// Compiler FORCES you to handle null:
name?.length           // safe call β€” returns null if name is null
name?.length ?: 0      // Elvis β€” returns 0 if name is null
name!!.length          // throws if null (use sparingly!)

Java: NullPointerException crashes at runtime ← bad
Kotlin: Null errors caught at compile time ← good

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q15 Β· Gradle & Dependencies 2 pts

What is the difference between implementation and testImplementation in build.gradle? When would you use each?

⏱ 60 seconds β€” discuss with your team
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q15 Answer βœ…

// build.gradle.kts
dependencies {
    // Shipped with the app β€” available everywhere
    implementation("androidx.compose.ui:ui:1.5.4")

    // Only for unit tests β€” NOT in final APK
    testImplementation("junit:junit:4.13.2")

    // Only for instrumented (device) tests
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
Keyword In APK? Use For
implementation βœ… Yes App code dependencies
testImplementation ❌ No JUnit, Mockito, etc.
androidTestImplementation ❌ No Espresso, UI tests
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

πŸ“Š Scoreboard Update

After Round 2

Round 1 max: 10 pts
Round 2 max: 10 pts
Running total max: 20 pts

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Round 3

πŸ’» Code Challenge

3 points each β€” Read, analyze, write!

90 seconds per question

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q16 Β· Read the Code 3 pts

What does this function return when called with listOf(85, 92, 67, 78, 95)?

fun mystery(scores: List<Int>): Map<String, Int> {
    return scores
        .groupBy { score ->
            when {
                score >= 90 -> "A"
                score >= 80 -> "B"
                score >= 70 -> "C"
                else        -> "F"
            }
        }
        .mapValues { it.value.size }
}
⏱ 90 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q16 Answer βœ…

Tracing through listOf(85, 92, 67, 78, 95):

85 β†’ B (β‰₯80, <90)
92 β†’ A (β‰₯90)
67 β†’ F (<70)
78 β†’ C (β‰₯70, <80)
95 β†’ A (β‰₯90)
// groupBy groups them:
{ "B" β†’ [85], "A" β†’ [92, 95], "F" β†’ [67], "C" β†’ [78] }

// mapValues { it.value.size } counts each group:
{ "B" β†’ 1, "A" β†’ 2, "F" β†’ 1, "C" β†’ 1 }

Return value: {"B"=1, "A"=2, "F"=1, "C"=1}

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q17 Β· Fix the Bug 3 pts

This composable has three bugs. Identify and fix them.

fun CounterCard() {
    var count = 0

    Card(modifier = Modifier.fillMaxWidth()) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text("Count: $count")
            Row {
                Button(onClick = { count-- }) { Text("-") }
                Button(onClick = { count++ }) { Text("+") }
            }
        }
    }
}
⏱ 90 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q17 Answer βœ… β€” 3 Bugs Fixed

@Composable                          // Bug 1: Missing @Composable
fun CounterCard() {
    var count by remember {          // Bug 2: Must use remember + mutableStateOf
        mutableStateOf(0)            //        Plain var resets every recomposition
    }

    Card(modifier = Modifier.fillMaxWidth()) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text("Count: $count")
            Row {
                Button(onClick = {
                    if (count > 0) count--   // Bug 3: Must prevent negative count
                }) { Text("-") }
                Button(onClick = { count++ }) { Text("+") }
            }
        }
    }
}
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q18 Β· Fill in the Blanks 3 pts

Fill in the 3 missing pieces to complete this navigation:

@Composable
fun AppNavigation() {
    val navController = ___β‘ ___()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(onGoToProfile = {
                navController.___β‘‘___("profile/Alice")
            })
        }
        composable("profile/{userName}") { backStackEntry ->
            val user = backStackEntry.___β‘’___?.getString("userName") ?: ""
            ProfileScreen(userName = user)
        }
    }
}
⏱ 90 seconds
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Q18 Answer βœ…

@Composable
fun AppNavigation() {
    val navController = rememberNavController()    // β‘  rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(onGoToProfile = {
                navController.navigate("profile/Alice")  // β‘‘ navigate()
            })
        }
        composable("profile/{userName}") { backStackEntry ->
            val user = backStackEntry.arguments          // β‘’ arguments
                ?.getString("userName") ?: ""
            ProfileScreen(userName = user)
        }
    }
}

β‘  rememberNavController() β€” creates and remembers the controller
β‘‘ navigate() β€” performs the navigation
β‘’ arguments β€” property on BackStackEntry holding nav args

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

πŸ† Final Scoreboard

Add up all three rounds!

Round Max
Round 1: Quick Fire (MC) 10 pts
Round 2: Short Answer Showdown 10 pts
Round 3: Code Challenge 9 pts
Total 29 pts
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

What's Actually on Friday's Exam

Section # Questions Points
Part 1: Multiple Choice 20 40 pts
Part 2: Short Answer 8 30 pts
Part 3: Code Writing 3 problems 30 pts
Total 100 pts

Allowed: One 8.5Γ—11" reference sheet (both sides, handwritten or typed by you)

Covers: Weeks 1–7 β€” Kotlin, Android platform, Compose, state, ViewModels, lists, navigation

Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Last-Minute Study Checklist

Can you do these without looking anything up?

  • [ ] Write var count by remember { mutableStateOf(0) } from memory
  • [ ] Explain what ?: does in one sentence
  • [ ] Name all 4 collection functions and what each returns
  • [ ] Describe what happens on device rotation (and why)
  • [ ] Write a NavHost with one route that takes an argument
  • [ ] Explain state hoisting with an example
  • [ ] Name 3 Android resource types and their file locations
  • [ ] Write a @Composable function with a Button and state
Week 9 Monday: Midterm Blitz Competition
CS 3180 Mobile Application Development

Wednesday: Practice Problems Session

  • Bring specific questions you're unsure about
  • We'll work through more coding examples live
  • Focus on Part 3 (code writing) β€” most students lose points there
  • Practice writing code on paper β€” no autocomplete on the exam!

Friday: Midterm Exam β€” 50 minutes

Good luck! You've got this.

Week 9 Monday: Midterm Blitz Competition

SPEAKER NOTES: Welcome to Midterm Blitz! Today every question is practice for Friday's exam. Desks in teams before we start. Pull up a blank sheet of paper for tracking scores.

SPEAKER NOTES: Give teams 2 minutes to form. Each team needs one spokesperson. They write answers on scratch paper, then hold up/reveal on count of 3. You track on whiteboard. Approximate time: 50 minutes for full deck.

SPEAKER NOTES: 10 MC questions drawn from the practice midterm. Keep the pace fast. Reveal the answer slide immediately after teams show their answers.

SPEAKER NOTES: Common mistake: confuse with JavaScript 'let/const'. In Kotlin, val = immutable reference, var = mutable. 'const' is only valid at top-level or in companion objects.

SPEAKER NOTES: Award 1 point to teams who answered B. Tip: default to val, only use var when you need to change the value.

SPEAKER NOTES: This trips up a lot of students. Rotation is a configuration change, which by default destroys and recreates the Activity. This is why ViewModels exist.

SPEAKER NOTES: Key follow-up question to ask the class: "So what DOES survive rotation without ViewModel?" Answer: Saved instance state (Bundle), but it has size limits.

SPEAKER NOTES: Emphasize "efficiently" β€” that's the key word. Column composes ALL items upfront. LazyColumn only composes what's visible.

SPEAKER NOTES: This will absolutely be on the exam. The word "lazy" = only does work when needed.

SPEAKER NOTES: Without remember, every recomposition reinitializes the variable to its default. remember = "keep this value alive through recompositions."

SPEAKER NOTES: Bonus discussion: what's the difference between remember and rememberSaveable? rememberSaveable survives process death and rotation.

SPEAKER NOTES: The format is: values-[language code]. Android uses BCP 47 language tags. Default strings live in values/, locale-specific in values-[locale]/.

SPEAKER NOTES: You can also use region qualifiers: values-es-rMX for Mexican Spanish. The -r prefix is required for region codes.

SPEAKER NOTES: ViewModel's MAIN job: outlive the Activity/Fragment through config changes. Secondary job: hold UI state/data. It does NOT directly do DB work (that's Repository/DAO).

SPEAKER NOTES: Draw the architecture diagram on the board: UI β†’ ViewModel β†’ Repository β†’ Room/Network. ViewModel is the buffer between UI and data.

SPEAKER NOTES: Each collection function has one job: map=transform, filter=select, reduce=combine into one, forEach=iterate with no return. Know these cold for the exam.

SPEAKER NOTES: Know these four cold. They will appear in the coding section. You can chain them: list.filter { it > 0 }.map { it * 2 }

SPEAKER NOTES: The ?: is called the Elvis operator (tilt your head left β€” looks like Elvis's hair). It's shorthand for "if this is null, use this default instead."

SPEAKER NOTES: Quick quiz: what does "name?.length ?: 0" return if name is null? Answer: 0. If name is "Alice"? Answer: 5.

SPEAKER NOTES: MD3 color system: primary = most prominent. onPrimary = content ON a primary-colored surface. secondary = less prominent actions. tertiary = contrasting accent.

SPEAKER NOTES: The naming convention: "on" prefix = what goes ON top of that color. primaryContainer = a lighter tint of primary for filled buttons.

SPEAKER NOTES: The API is simply navController.navigate(). navigateTo() doesn't exist. goTo() and push() are from other frameworks (web router, iOS UINavigationController).

SPEAKER NOTES: Both navigate() forms are valid β€” string-based and type-safe. The exam may use either. navigateUp() is preferred over popBackStack() for the "up" button in the app bar.

SPEAKER NOTES: Round 2 is more collaborative. Give teams 60 seconds to discuss together, then cold-call a team OR let teams volunteer. Award points based on quality of answer.

SPEAKER NOTES: Listen for: val = immutable/read-only, cannot be reassigned. var = mutable, can be reassigned. Good examples: val for navController (doesn't change), var for a counter state variable.

SPEAKER NOTES: Award 1 pt for correct definitions, 1 pt for good examples. Full credit if they say "prefer val, only use var when needed."

SPEAKER NOTES: Key terms to listen for: "move state up to caller", "stateless composable", "single source of truth", "reusable", "testable".

SPEAKER NOTES: Award 1 pt for correct definition, 1 pt for 2+ reasons why it matters. The stateless composable is easier to preview, test, and reuse in different contexts.

SPEAKER NOTES: Looking for: Created, Started, Resumed, Paused, Stopped, Destroyed. Transitions: Created→Started when visible, Started→Resumed when in foreground, Resumed→Paused when dialog covers it, etc.

SPEAKER NOTES: Award 1 pt for 4 correct states, 1 pt for 2 correct transitions. Common mistake: students say "crashes" on rotation β€” correct answer is Stopped β†’ Destroyed β†’ re-Created.

SPEAKER NOTES: Listen for: type system separates nullable (String?) from non-nullable (String), compiler forces you to handle null, prevents NullPointerException at runtime by catching at compile time.

SPEAKER NOTES: Award 1 pt for explaining nullable vs non-nullable, 1 pt for explaining compile-time vs runtime safety. Java has the "billion-dollar mistake" β€” null references.

SPEAKER NOTES: Key distinction: implementation = included in final APK, testImplementation = only for unit tests, not shipped to users.

SPEAKER NOTES: Award 1 pt for each correct definition. Real-world reason: no point shipping test libraries to users β€” it bloats the APK.

SPEAKER NOTES: 3 coding questions. Teams may discuss but each person writes their answer. Award partial credit for close answers. Full credit requires correct syntax + logic.

SPEAKER NOTES: Answer: {"B"=2, "A"=2, "C"=1} β€” Wait, let me trace: 85β†’B, 92β†’A, 67β†’F, 78β†’C, 95β†’A. So: A=[92,95], B=[85], C=[78], F=[67]. mapValues gets size. Result: {A=2, B=1, C=1, F=1}

SPEAKER NOTES: Award: 1 pt for correct grouping logic, 1 pt for understanding mapValues, 1 pt for correct final answer. Partial credit for close answers. This is a simplified version of the exam's processStudentGrades problem.

SPEAKER NOTES: 3 bugs: 1) Missing @Composable annotation, 2) var count = 0 should be var count by remember { mutableStateOf(0) }, 3) No check preventing count from going below 0 (decrement should be if count > 0).

SPEAKER NOTES: Award 1 pt per correctly identified and fixed bug. Bug 1: without @Composable it won't compile. Bug 2: without remember, count resets to 0 on every recomposition (tap the button, nothing appears to happen). Bug 3: requirement says can't go below 0.

SPEAKER NOTES: β‘  rememberNavController, β‘‘ navigate, β‘’ arguments. These are the three most testable navigation pieces.

SPEAKER NOTES: Award 1 pt per correct blank. Common mistake for β‘’: students write "backStackEntry.getString" directly, but the arguments property is a Bundle that holds the args.

SPEAKER NOTES: Final tally. Announce winner(s). If time permits, ask the winning team: "What's one thing you're still nervous about for the exam?" β€” good way to surface remaining gaps.

SPEAKER NOTES: Review the exam structure. Remind them: reference sheet is a tool, not a crutch. The process of making it is the studying.

SPEAKER NOTES: Walk through this checklist verbally. Ask "hands up if you feel good about this." That's a quick formative assessment for you to know what to focus on in Wednesday's session.

SPEAKER NOTES: End with energy. Wednesday is more hands-on β€” plan to do live coding with students at the board. Friday's exam: doors close 5 minutes after start.