Year #3, Week #22 đť đ¤ż
Homework Plan
- Watch Tidbits addendum video
- 1 day watch CS50
CS50 Lecture #5 segment,
from
30.23
to1:08:24
- 1 day Monkey Assignment #31 đ
- 1 day Monkey Assignment #32 đ
- 2 days review all flashcards in your (new Netlify) app.
- 1 day read King C chapter 17 đ
- 1 day King C programming exercizes/projects đ
- 2 days touch typing practice
- 2 days Flashcards API assignment
- 6 days Execute Program homework
Flashcards API assignment #1
Make sure youâve first watched the tidbits video.
Make sure youâve addressed all feedback from any prior MRs, and merged.
read all these instructions from beginning to end before starting
this homework has a video, you can use it if you need it, but try first to do it without (link at the end)
Implement a new API route:
POST /categories
, as I described in class, with the presence or lack of anid
field being the differentiator between whether we are editing a category, or creating a categoryRegarding the methods/functions etc, outlined below: you are encouraged to change the names of the methods, arguments, or even the shape/types of the arguments, to match your naming convention and personal coding style. The naming and type signatures arenât a requirement, but they do show you what information you almost certainly will need for each function.
Below are a some hints and requirements:
you will need to end up adding 3 new database methods:
- one to return a
User
row/resource from a token:
getUserFromToken: (token: string) => Promise<Result<Omit<UserRow, 'password'>>>;
- one to insert a new category:
insertCategory: (name: string) => Promise<Result<CategoryRow>>;
- edit an existing category:
editCategory: ( id: string, name: string, ) => Promise<Result<Pick<CategoryRow, 'id' | 'name'>>>;
- one to return a
you will need add a new âroute responderâ for editing a category:
updateCategory(
db: Database,
authorizationHeader: string | undefined,
body: any
): Promise<Response>;
- the route responder method shown above takes a
authorizationHeader
param for a basic authorization sanity check, usingdb.getUserFromToken(...)
. That method on the db will be used more extensively in Part 2 of this homework, but weâll also use it in thisupdateCategory()
route responder to do a sanity check that we have a valid authenticated user making the request. What I mean by that is, inside the route responder you should:- pull the bearer token from the header (like you do in the
GET /cards
route) - then call
db.getUserFromToken()
- if you get a valid user, fine, proceed (without using any of the actual user data)
- if you canât find a valid user, immediately return with an âunauthorizedâ message/status â only valid authenticated users are allowed to use this route.
- you might find some commonality between this responder and the
getCards
responder, in the code that pulls the token from the header, and it might be worth factoring out some duplication in a helper method.
- pull the bearer token from the header (like you do in the
- the route responder takes as itâs
body
argument the parsed JSON body, which is why itâs anany
. In order to extract valid, type-safe info from the parsed json blob, I want you to make a function like this (where if the data is not valid, it returnsnull
):
function validCategoryData(body: any): null | {
id?: string; // đ `id` is optional
name: string;
};
- the route responder will call that method with the
body: any
argument it gets passed. If it getsnull
back, the request was not valid, so it can return a â400/Bad Requestâ response. If it gets some non-null valid data, it will use that to safely pass arguments on to the database methods. - your route responder should be extensively tested, including
- asserting that you get a â400/Bad Requestâ response if you pass in invalid
body
data. - asserting that the database method to insert a category is called when an
id
is NOT present - asserting that the database method to edit a category is called when an
id
IS present - covering failure and error cases
- asserting that you get a â400/Bad Requestâ response if you pass in invalid
- you must add a two new requests to your
api.http
that allows you to test adding and updating a category. - commit your work
- Push up a MR
- Review your diffs
- Slack me the MR
- When I approve your MR donât merge it, then you may continue to part 2.
- video link #1
- video link #2
Flashcards API Assignment #2
Make sure youâve addressed all feedback from from your WIP/partial MR in part 1 of the assignment.
read all these instructions from beginning to end before starting
this homework does not have a video, but is conceptually very similar to part 1, only with a couple more bits of data because the
cards
table has more columns than thecategories
table. But all the concepts are the same, so you should be able to follow the outline of your work for part 1, and do it mostly the same.Implement a new API route:
POST /cards
, as I described in class, with the presence or lack of anid
field being the differentiator between whether we are editing a card, or creating a cardBelow are a some hints and requirements:
you will need to end up adding 2 new database methods:
- one to insert a new card:
insertCard( userId: string, categoryId: string, front: string, back: string, ): Promise<Result<Pick<Card, 'id' | 'title' | 'back'>>>;
- edit an existing card:
editCategory(id: string, name: string)
editCard( id: string, categoryId: string, front: string, back: string, ): Promise<Result<Pick<Card, 'id' | 'title' | 'back'>>>;
you will need add a new âroute responderâ for editing a card:
updateCard(
db: Database,
authorizationHeader: string | undefined,
body: any
): Promise<Response>;
- This route responder also uses
db.getUserFromToken()
, but for 2 reasons â authentication, and getting the users id for foreign key relations â (unlike theupdateCategory()
responder, which used it only for authentication) - the route responder also takes as itâs
body
argument the parsed JSON body, which is why itâs anany
. Make another input/body validator function:
function validCardData(body: any): null | {
id?: string; // `id` optional again
categoryId: string;
front: string;
back: string;
};
- the route responder will call that method with the
body: any
argument it gets passed. If it getsnull
back, the request was not valid, so it can return a â400/Bad Requestâ response. If it gets some non-null valid data, it will use that to safely pass arguments on to the database methods. - your route responder should be extensively tested, including
- asserting that you get a â400/Bad Requestâ response if you pass in invalid
body
data. - asserting that the database method to insert a card is called when an
id
is NOT present - asserting that the database method to edit a card is called when an
id
IS present - covering failure and error cases
- asserting that you get a â400/Bad Requestâ response if you pass in invalid
- you must add a two new requests to your
api.http
that allows you to test adding and updating a card. - commit your work
- Push up a MR
- Review your diffs
- Slack me the MR
Monkey #31 đ
- Address all feedback from prior MR, and merge.
- Create a new branch.
- Double-check that you did the first two steps.
- Start at the beginning of the section titled: 4.4 Arrays
- Stop at the beginning of the sub-section titled Parsing Index Operator
Expressions, at the top of page 169 (PDF), or the middle of 213 (printed),
right where he says
We can mark âparsing array literalsâ as âdoneâ.
- Commit your work.
- As always, make sure to try to do as much as you can without the videos, but always also watch the videos and update your code to (mostly) match.
- Video link
- Submit a MR, Review your diffs and fixup!!, then slack the MR url
Monkey #32 đ
- Address all feedback from prior MR, and merge.
- Create a new branch.
- Double-check that you did the first two steps.
- Start at the beginning of the sub-section titled: Parsing Index Operator Expessions (p. 169 pdf, p. 213 printed)
- Stop at the beginning of the sub-section titled Evaluating Array
Literals (p. 172 pdf, p. 217 printed), right where he says
Lexer done, parser done. See you in the evaluator!
- Commit your work.
- As always, make sure to try to do as much as you can without the videos, but always also watch the videos and update your code to (mostly) match.
- Video link
- Submit a MR, Review your diffs and fixup!!, then slack the MR url
King C Assignment đ
Make sure youâve first watched the tidbits video.
First, watch the CS50 video segment assigned for this week
Slowly and carefully read Chapter 17 of King C skip the last two sections, on restricted pointers and flexible array members (section
17.8
, and17.9
) - but DO READ THE Q&A (it gives you part of the answer for the homework).Merge your
king-c
repo branch from a few weeks ago, and CREATE A NEW BRANCH.Read the whole assignment before starting
Project #1:
- Write a program that sorts a series of words entered by the user, a session would look like this:
Enter word: zoo Enter word: foobar Enter word: cat Enter word: Apple Enter word: You entered 4 words: Apple cat foobar zoo Meow!
- When the user enters an empty word (i. e., presses âEnterâ without entering a word), stop storing words and print the sorted list.
- The list of words must be stored in a heap-allocated Linked List.
- You may assume that each word is no longer than 20 characters long.
- Use the
read_line()
 function here to get a word from the user. - Your program must not leak memory.
- You must check for
NULL
pointers whenever you malloc and exit/return when necessary. - You must make a function called
make_node
that takes achar[]
(or achar*
) and returns a pointer to a node. This function should be used by your program. - when adding to your list, the new node should be put at the beginning.
- You must make a function called
count_list
which counts the number of items in the list, starting with the head node. You must use this function to calculate the number when writing the lineYou entered 4 words.
shown in the example above. - make a function
bool in_list(char* word, node* list)
function that allows you to search for a string contained anywhere in the list. Use this function to test if the user has written the wordcat
orCat
. If so, printMeow!
as the last line. - Extra Credit: ⨠Add a line of output printing the words in sorted
order. Do the sort using
qsort
, as described/shown in the chapter. Hint: you canât pass a linked list toqsort
, so determine the number of items, and convert the list to a variable-length-array, then pass that toqsort
. The code in the chapter and in the Q&A section will be very helpful for this.
Project #2 Extra Credit â¨
- write a program that stores integers from the user, and then prints them in sorted order:
Enter number: 7 Enter number: 3 Enter number: 99 Enter number: -2 Enter number: You entered 4 numbers: -2, 3, 7, 99
- To achieve this, store the numbers entered by the user in a sorted linked list.
- When the user enters a blank line, just iterate through your linked list, printing out each number, they should already be sorted, since youâre keeping them sorted at the time of insertion.
- your program must not leak memory
- make sure youâve handled the case where you need to enter a number between two existing numbers, like when the user enters 5, 7, 6.
- hint: some of the code in the chapter comes very close to supplying what you need to make this work.