Skip to content

Commit 578490c

Browse files
committed
reachitect grade-school
1 parent 2d1cfd8 commit 578490c

File tree

10 files changed

+4229
-0
lines changed

10 files changed

+4229
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Instructions
2+
3+
Given students' names along with the grade that they are in, create a roster
4+
for the school.
5+
6+
In the end, you should be able to:
7+
8+
- Add a student's name to the roster for a grade
9+
- "Add Jim to grade 2."
10+
- "OK."
11+
- Get a list of all students enrolled in a grade
12+
- "Which students are in grade 2?"
13+
- "We've only got Jim just now."
14+
- Get a sorted list of all students in all grades. Grades should sort
15+
as 1, 2, 3, etc., and students within a grade should be sorted
16+
alphabetically by name.
17+
- "Who all is enrolled in school right now?"
18+
- "Let me think. We have
19+
Anna, Barb, and Charlie in grade 1,
20+
Alex, Peter, and Zoe in grade 2
21+
and Jim in grade 5.
22+
So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe and Jim"
23+
24+
Note that all our students only have one name. (It's a small town, what
25+
do you want?)
26+
27+
## For bonus points
28+
29+
Did you get the tests passing and the code clean? If you want to, these
30+
are some additional things you could try:
31+
32+
- If you're working in a language with mutable data structures and your
33+
implementation allows outside code to mutate the school's internal DB
34+
directly, see if you can prevent this. Feel free to introduce additional
35+
tests.
36+
37+
Then please share your thoughts in a comment on the submission. Did this
38+
experiment make the code better? Worse? Did you learn anything from it?
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "grade_school2.h"
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
static roster_t roster = { 0 };
6+
7+
static bool student_is_on_roster(char *name, roster_t roster)
8+
{
9+
bool is_on_roster = false;
10+
for (size_t i = 0; i < roster.count; ++i) {
11+
if (!strncmp(roster.students[i].name, name, MAX_NAME_LENGTH)) {
12+
is_on_roster = true;
13+
break;
14+
}
15+
}
16+
return is_on_roster;
17+
}
18+
19+
static int compare_student_names(const void *s1, const void *s2)
20+
{
21+
const student_t *student1 = (const student_t *)s1;
22+
const student_t *student2 = (const student_t *)s2;
23+
return strncmp(student1->name, student2->name, MAX_NAME_LENGTH);
24+
}
25+
26+
static int compare_student_grades_and_names(const void *s1, const void *s2)
27+
{
28+
const student_t *student1 = (const student_t *)s1;
29+
const student_t *student2 = (const student_t *)s2;
30+
31+
if (student1->grade > student2->grade)
32+
return 1;
33+
else if (student1->grade < student2->grade)
34+
return -1;
35+
else
36+
return compare_student_names(student1, student2);
37+
}
38+
39+
bool add_student(char *name, uint8_t grade)
40+
{
41+
bool added = false;
42+
43+
if (student_is_on_roster(name, roster)) {
44+
added = false;
45+
} else if (roster.count < MAX_STUDENTS && strlen(name) < MAX_NAME_LENGTH) {
46+
strcpy(roster.students[roster.count].name, name);
47+
roster.students[roster.count].grade = grade;
48+
++roster.count;
49+
qsort(roster.students, roster.count, sizeof(roster.students[0]),
50+
compare_student_grades_and_names);
51+
added = true;
52+
}
53+
54+
return added;
55+
}
56+
57+
roster_t get_roster(void)
58+
{
59+
return roster;
60+
}
61+
62+
roster_t get_grade(uint8_t grade)
63+
{
64+
roster_t grade_roster = { 0 };
65+
66+
for (size_t i = 0; i < roster.count && grade_roster.count < MAX_STUDENTS;
67+
++i) {
68+
if (roster.students[i].grade == grade) {
69+
strcpy(grade_roster.students[grade_roster.count].name,
70+
roster.students[i].name);
71+
grade_roster.students[grade_roster.count].grade = grade;
72+
++grade_roster.count;
73+
}
74+
}
75+
return grade_roster;
76+
}
77+
78+
void clear_roster(void)
79+
{
80+
memset(&roster, 0, sizeof(roster));
81+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef GRADE_SCHOOL2_H
2+
#define GRADE_SCHOOL2_H
3+
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
#include <stdbool.h>
7+
8+
#define MAX_NAME_LENGTH 20
9+
#define MAX_STUDENTS 20
10+
11+
typedef struct {
12+
uint8_t grade;
13+
char name[MAX_NAME_LENGTH];
14+
} student_t;
15+
16+
typedef struct {
17+
size_t count;
18+
student_t students[MAX_STUDENTS];
19+
} roster_t;
20+
21+
bool add_student(char *name, uint8_t grade);
22+
23+
roster_t get_roster(void);
24+
25+
roster_t get_grade(uint8_t grade);
26+
27+
void clear_roster(void);
28+
29+
#endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "grade_school2.h"
2+
3+
static roster_t roster = { 0 };
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef GRADE_SCHOOL2_H
2+
#define GRADE_SCHOOL2_H
3+
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
7+
#define MAX_NAME_LENGTH 20
8+
#define MAX_STUDENTS 20
9+
10+
typedef struct {
11+
uint8_t grade;
12+
char name[MAX_NAME_LENGTH];
13+
} student_t;
14+
15+
typedef struct {
16+
size_t count;
17+
student_t students[MAX_STUDENTS];
18+
} roster_t;
19+
20+
#endif
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
### If you wish to use extra libraries (math.h for instance),
2+
### add their flags here (-lm in our case) in the "LIBS" variable.
3+
4+
LIBS = -lm
5+
6+
###
7+
CFLAGS = -std=c99
8+
CFLAGS += -g
9+
CFLAGS += -Wall
10+
CFLAGS += -Wextra
11+
CFLAGS += -pedantic
12+
CFLAGS += -Werror
13+
CFLAGS += -Wmissing-declarations
14+
CFLAGS += -DUNITY_SUPPORT_64
15+
16+
ASANFLAGS = -fsanitize=address
17+
ASANFLAGS += -fno-common
18+
ASANFLAGS += -fno-omit-frame-pointer
19+
20+
.PHONY: test
21+
test: tests.out
22+
@./tests.out
23+
24+
.PHONY: memcheck
25+
memcheck: ./*.c ./*.h
26+
@echo Compiling $@
27+
@$(CC) $(ASANFLAGS) $(CFLAGS) test-framework/unity.c ./*.c -o memcheck.out $(LIBS)
28+
@./memcheck.out
29+
@echo "Memory check passed"
30+
31+
.PHONY: clean
32+
clean:
33+
rm -rf *.o *.out *.out.dSYM
34+
35+
tests.out: ./*.c ./*.h
36+
@echo Compiling $@
37+
@$(CC) $(CFLAGS) test-framework/unity.c ./*.c -o tests.out $(LIBS)

0 commit comments

Comments
 (0)