New to racket, help with coursework question

275 views
Skip to first unread message

Suz Renae

unread,
Apr 19, 2020, 2:50:50 PM4/19/20
to Racket Users
I am new to racket (first year student) and since class has been pushed to online only, I am having a harder time.

We are currently working on vectors and hash tables. I feel like I keep overthinking it and keep getting stuck. I know that the first parameter in the function will be the year and the second will be the (vector-ref months x)that I pull from the defined vector.

The question I am having a hard time with and what I have actually done below.

Create a function that calculates the number of days in a month given a year and a month
  • Call the function number-of-days-in-month, and it's signature is number, number -> number
  • Example:
    (number-days-in-month 2016 1) -> 31
    (number-days-in-month 2016 11) -> 30
    (number-days-in-month 2016 12) -> 31
    (number-days-in-month 1900 2) -> 28
    (number-days-in-month 2000 2) -> 29
    (number-days-in-month 2016 2) -> 29
    (number-days-in-month 2200 2) -> 28
What I have so far...

;Leap Year
(define (leap-year? year)
  (and (zero? (modulo year 4))
       (or (not (zero? (modulo year 100)))
          (zero? (modulo year 400))
          )
       )
  )

;Months with days vector, beginning at an index of 0 since there is not 0th month
(define months (vector 0 31 28 31 30 31 30 31 31 30 31 30 31))

(check-expect(number-days-in-month 2016 1)31)
(check-expect(number-days-in-month 2016 11)30)
(check-expect(number-days-in-month 2016 12)31)
(check-expect(number-days-in-month 1900 2)28)
(check-expect(number-days-in-month 2000 2)29)
(check-expect(number-days-in-month 2016 2)29)
(check-expect(number-days-in-month 2200 2)28)

I  need help with building the actual function and what conditionals I should be using.

(define (number-days-in month ?? ??)
    (cond
         [

Jon Zeppieri

unread,
Apr 19, 2020, 3:58:20 PM4/19/20
to Suz Renae, Racket Users
Well, this all looks very familiar. Can I ask where this course is offered?


Okay, let's start with part of the problem definition:

> Create a function that calculates the number of days in a month given a year and a month
>
> Call the function number-of-days-in-month, and it's signature is number, number -> number

Let's put these two statements together. In fact, let's start with the
second one, specifically: "[the function's] signature is number,
number -> number." That means the function takes two arguments, both
of which are numbers, and it returns a number. That's not very
informative. If that were all the information you had, you might start
your function definition like this:

(define (number-of-days-in-month one-number a-second-number)
[ somehow calculate yet a third number ])

But the previous sentence gives you more information. It says, "[the
function] calculates the number of days in a month given a year and a
month." This is a actually a more specific version of what the
signature tells you. Let me reverse the order of the statement to make
this more clear: "Given a year and a month, the function calculates
the number of days in the month."

So the "numbers" in the signature aren't any old numbers. Let's look
at the signature again:
number, number -> number

The things to the left of the arrow are what the function is given.
The problem says that the function is given a year and a month. So
let's restate the signature, adding that information:
year-number, month-number -> number

The thing to the right of the arrow is what the function calculates,
in this case the number of days in the given month. (This is where
things get a little complicated. You're trying to calculate the number
of days in the month that you're given. Fine, so why are you given a
year in addition to the month? The answer to this question will help
you when you start to fill in your function body. By the way, I'm not
trying to be patronizing. I'm pretty sure you know the answer to this
question, given what you wrote in your message. But it may help to
think about it this way.) So let's add this information to the
signature:

year-number, month-number -> number-of-days-in-month

Or, in English: "`number-of-days-in-month` is a function that takes a
year number and a month number and returns the number of days in the
month." If you're skeptical of my claim that this is more specific
than the signature we started with, consider that not all numbers are
valid year-numbers or month-numbers. For example, 2.5 isn't the number
of a year (well, not in the Gregorian calendar, anyhow), and -20 isn't
the number of a month.

So now at least, we should be able to replace the "??"s in your
function skeleton:

(define (number-days-in-month year-number month-number)
(cond
[

As for the conditional in the function body, go back to the question I
posed above: why are you given a year-number in addition to a
month-number if you're just supposed to find the number of days in a
month?

- Jon
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/5d017eef-b235-4a8b-94fa-fe1e3f7b766e%40googlegroups.com.

John Clements

unread,
Apr 19, 2020, 3:59:48 PM4/19/20
to Suz Renae, Racket Users
First off: you’re very close.

Thing two: I think you need a clearer comment on the meaning of the “months” vector. Your description does not actually say what the vector represents or contains.

Thing three: Here’s my question to you. Suppose that I tell you a year and a month and the result of (vector-ref months x).

To be more concrete, suppose I tell you the year is 2234 and the month is 4 and the result of (vector-ref months x) is 30. How many days would that month have? Can you explain how to compute the answer for each of the test cases below?

John Clements

Suz Renae

unread,
Apr 19, 2020, 4:13:56 PM4/19/20
to Racket Users
Thank you for replying. The course is at Mesa College in San Diego. Intro to Computer Science. Not as easy as I thought it would be.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket...@googlegroups.com.

Suz Renae

unread,
Apr 19, 2020, 4:20:57 PM4/19/20
to Racket Users
The months vector is representing each month and how many days are in that month. 
(define months (vector 0 31 28 31 30 31 30 31 31 30 31 30 31))
31 would be 1 or January (since all indexes start at 0, there is no 0th month), 28 would be 2 or February, and so forth and so on. So if we did (vector-ref months 1) -> 31

I know how to read code, but writing it is my problem. This is my first coding class. So I don't know if I can write a parameter in the definition using vector-ref....like 
(define (number-days-in-month year (vector-ref months x)
     (cond
      [if (= y leap-year?
                 29
                 28

Or even with that above, how would it know that leap-year? only effects month 2. I am highly confused unfortunately. 
> To unsubscribe from this group and stop receiving emails from it, send an email to racket...@googlegroups.com.

Matt Jadud

unread,
Apr 19, 2020, 5:39:56 PM4/19/20
to Suz Renae, Racket Users
This is good. Your questions are good, and while the frustration/confusion is real, don't let it get you down. It's just part of the process. (That is, learning often involves confusion and frustration.)

This might step it back too far, but see if this helps a bit. Your question about what you can put in the definition suggests that you're in a good place, but you've got a lot of ideas swimming around all at once. Let's try this.

A function definition has a pattern to it.

(define (__A__ __B__)
  __C__)

When you look at a definition, you want to look for that pattern. Use DrRacket's highlighting to help you see the pieces if you need to. I find it handy all the time.

"A" is the name of the thing you are defining, "B" is a parameter, and "C" is the body. There can, of course, be multiple parameters. Then, the pattern looks like:

(define (__A__ __B1__ __B2__)
  __C__)

assuming you have a function definition with two parameters.

Making it a bit more concrete, you could have a function like this:

;; CONTRACT
;; number -> number
(define (add-one n)
  (+ n 1))

which, if you paste that into the "Interactions" area in DrRacket, and hit return, you will define the function. If you then type:

(add-one 3)

you will see that it evaluates to 4. That is because the value of '3' is bound to the parameter 'n', and then the body is evaluated (or "run") with n having the value 3. When you add one to three, you get four. Or, (+ 1 3) evaluates to 4.

In the second pattern, you might have:

;; CONTRACT
;; number number -> number
(define (add-nums a b)
  (+ a b))

and then you could invoke or use that function as:

(add-nums 3 5)

Here, the value '3' is bound to 'a', 5 is bound to 'b', and then 'a' and 'b' are summed, giving you 8.

Coming back around to your question, you're wondering "but where do I put the vector-ref?" Hopefully, along with the excellent questions you've been asked so far, the great answers that have been provided, and my potentially confusing message here, you're starting to think "perhaps I don't put the vector-ref in the parameters..."

The contract for 'number-of-days-in-month' was given to you as

number number -> number

which means that 'number-of-days-in-month' takes two parameters. You need to give each of those parameters names. Or, in a pattern:

;; CONTRACT
;; number number -> number
(define (number-of-days-in-month __B1__ __B2__)
 __C__)

You need to give names to the two parameters (which you know what they have to be... and you've already said what those two parameters are, so naming them is something I suspect you can do). Then, you need to *do stuff* in __C__. Or, as John suggested, this is where you do the calculation that needs to be done... if you can write it out, you're a long way along to filling in __C__. When you're writing the body of the function (or __C__ in my pattern), I suspect you're going to need to use those two parameters---which represent a year and month---to do your calculation.

Then, you would run that function this way:

(number-days-in-month 2016 1)

(which I just copy-pasted from your first email) and 2016 would be bound to the first parameter (whatever you called it), and 1 would be bound to the second. It would then run the body of the function, and the parameters would be bound to the values 2016 and 1.

That may, or may not, have helped. But hopefully it helps you step back from the code, which may be looking like a whole bunch of symbols right now, and encourage you to look for the patterns that are there, and what the parts of the patterns mean.

Keep asking questions,
Matt





To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/e057a97b-2ee0-4114-abd4-b2fc208dc3fa%40googlegroups.com.

Kristina Marie

unread,
Apr 20, 2020, 1:34:54 AM4/20/20
to Matt Jadud, Racket Users
I wanted to thank you all. I did it! My head hurts, but now seeing how simple it was, it hurts that it hurts.

;leap year

(define (leap-year? year)
  (and (zero? (modulo year 4))
       (or (not (zero? (modulo year 100)))
          (zero? (modulo year 400))
          )
       )
  )

;Months with days vector, beginning at an index of 0 since there is not 0th month
(define leap-year-months (vector 0 31 29 31 30 31 30 31 31 30 31 30 31))
(define ordinary-year-months (vector 0 31 28 31 30 31 30 31 31 30 31 30 31))

(check-expect(days-in-month 2016 1)31)
(check-expect(days-in-month 2016 11)30)
(check-expect(days-in-month 2016 12)31)
(check-expect(days-in-month 1900 2)28)
(check-expect(days-in-month 2000 2)29)
(check-expect(days-in-month 2016 2)29)
(check-expect(days-in-month 2200 2)28)


(define (days-in-month x y)
  (cond
    [(leap-year? x) (vector-ref leap-year-months y)]
    [else (vector-ref ordinary-year-months y)]
    )
  )

David Storrs

unread,
Apr 20, 2020, 11:29:54 AM4/20/20
to Kristina Marie, Matt Jadud, Racket Users
Great job!

For the record: Yes, it is entirely possible to have an 'if' clause choose the arguments to a function. This is legal:

(define first-element (vector-ref some-vector (if (equal? type 'zero-indexed) 0 1)))

As is this, which is more relevant to your exercise:

(define leap-year-months (vector 0 31 29 31 30 31 30 31 31 30 31 30 31))
(define ordinary-year-months (vector 0 31 28 31 30 31 30 31 31 30 31 30 31))

(vector-ref (if (is-leap-year? month) leap-year-months ordinary-year-months) month)


The other people in the thread have already given great advice, but I'll toss in my $0.02 for how to approach programming in general:

1) Be sure that the problem is clearly defined.  Look for edge cases and get them nailed down as early as possible.
2) Figure out how *you*, an intelligent human being, would solve the problem if asked to do it manually
3) Make the computer do that.

This won't solve every problem and it won't necessarily result in the most elegant or efficient solution, but it will generally get you *a* solution, which is the important part.   You can always optimize something but you can't optimize nothing.

For example, if the owner of BigCompany asks you to "Figure out how many people work here", you might do something like this:

1) Define the problem and look for edge cases
- Does 'here' mean only people working in the physical building, or do remote employees count?

- Do you include only full-time W-2 employees?  What about contractors?  Part-timers?  People like janitors and plant-maintenance staff who aren't employed by BigCompany but are employed by a service company that BigCompany retains and do jobs related to BigCompany?


2) Figure out how you would solve it yourself.
- Check with HR to get the number of people employed by BigCompany
- Check with the office manager to find out all the third-party companies that provide services to BigCompany
- Ask each of those companies how many people they have working on BigCompany-related tasks


3) Make the computer do that
- Connect to the HR database and do a query for all people employed by BigCompany
- Connect to the OM's database and do a query for all service companies retained by BigCompany
- Connect to the HR databases of each of those service companies and do a query for all of their employees who are assigned to work on BigCompany-related tasks



The number-of-days challenge was probably pretty frustrating, but hopefully the 'aha' moment at the end was worth it.  Stick with it; computer programming is often frustrating, but it's also immensely rewarding.  The sheer joy of creation added to the knowledge that your software **actually does something that helps people** is a wonderful feeling.

Reply all
Reply to author
Forward
0 new messages