I tried a calendar problem in Ruby

I'm a beginner studying Rails. It's been about a month since I first learned rails. While I wanted to start learning Ruby from scratch, I arrived at the following article written by Mr. Ito, a Ruby programmer.

If you have trouble with the output material, this is it! ?? I collected programming problems for Ruby beginners (10 questions in total)

Today, I will refer to this and write about the code I wrote and what I learned in it. I would like to continue to brush up on my own, but I would be happy if other people could see it and point out.

Calendar problem My answer First of all, my program I made is as follows.

calender.rb



require  'Date'

#Method to check the last day of this month
def last_day(year,month)
  if month == 2 && Date.valid_date?(year,month,29)
    return 29
  elsif month == 2
    return 28
  elsif Date.valid_date?(year,month,31)
    return 31
  else
    return 30
  end
end

#See how many weeks this month is
def how_many_weeks(day_array)
  days_count = day_array.length
  if days_count / 7 == 5 && days_count % 7 != 0
    return 6
  elsif days_count / 7 == 5
    return 5
  elsif days_count / 7 == 4 && days_count % 7 != 0
    return 5
  else
    return 4
  end
end

#Generate today's date
today = Date.today

#Year from today's date/Month/Monthの英字名を出力する
year = today.year
month = today.month
name_of_month = today.strftime("%B")

#Find out the start day of the month
day_of_the_week = Date.new(year,month,1).wday


#Create an array of dates based on the last date
last_day = last_day(year,month)
day_array = [*1..last_day]

#Add a blank to the array for each start day
day_of_the_week.times do
  day_array.unshift(" ")
end

#See how many weeks this month is
weeks_count = how_many_weeks(day_array)
#Creating a calendar title
calender_title = name_of_month + " " + year.to_s


#Calendar output
puts calender_title.center(21," ")
printf("%3s%3s%3s%3s%3s%3s%3s\n","Su","Mo","Tu","We","Th","Fr","Sa","Su")
weeks_count.times do
  #Set to one week's content week
  week = day_array.shift(7)

  #As a countermeasure in the case of nil, leave a blank
  if week.length < 7
    e  = week[6]
    week.map {|e| e ? e : " " }
  end

  #Output one week's worth
 printf("%3s%3s%3s%3s%3s%3s%3s\n",
        week[0],week[1],week[2],week[3],week[4],week[5],week[6])
end


The output result is as follows this month


     August 2020     
 Su Mo Tu We Th Fr Sa
                    1
  2  3  4  5  6  7  8
  9 10 11 12 13 14 15
 16 17 18 19 20 21 22
 23 24 25 26 27 28 29
 30 31   

Ruby features learned during creation

・ printf A function that prints after specifying the display format with a format specifier, which is derived from C language. I found this when I was thinking about how to shape the calendar when creating it. This time, it is used to output the day of the week and the date in the header part.
printf("%3s%3s%3s%3s%3s%3s%3s\n","Su","Mo","Tu","We","Th","Fr","Sa","Su")

Indicates output as a string with % s Specify the number of display digits with 3 in the meantime There is a line break at the last \ n.

By specifying the same format for the header part and the date, I was able to arrange it neatly.

Reference: Standard input function

・ String # center I noticed that the title cannot be centered with the above printf, and I found this method while investigating how to center a string with ruby.
puts calender_title.center(21," ")

Here, we are processing to have "" (blank) inserted so that the characters are in the center within the range of 21 which is the size of the calendar part. It's convenient!

Reference: String # center Ruby Reference

・ Map method that leaves nil blank The calendar should have blanks at the beginning and end depending on the day of the week of the first day. Regarding the beginning, I dealt with it by adding a blank to the array according to the day of the week to `day_array` with a date, but for the blank at the end, I do not know how to deal with it well, so it may be a burning blade. I used the following method.
  #Set to one week's content week
  week = day_array.shift(7)

  #As a countermeasure in the case of nil, leave a blank
  if week.length < 7
    e  = week[6]
    week.map {|e| e ? e : " " }
  end

if week.length < 7 If the week array with the date of the week has less than 7 elements e = week[6] By calling week [6], put nil in all the parts that have no value. week.map {|e| e ? e : " " } From there, use map to perform a ternary operation (replace with "" (blank) in the case of nil) and replace nil.

I think there is a better way, but ... I wanted to make it once, so I decided to do this.

Reference: How to manage nil of array and value so as not to cause an error in ruby

Finally

For the time being, I was able to make it very enjoyably through various trials and errors. As mentioned in the blog at the beginning, I think it is important to think more and make the code cleaner, not just to make it. Let's start by reviewing the code of this calendar creation app again and writing a test.

Once again, thank you to each site for your reference!

Recommended Posts

I tried a calendar problem in Ruby
I tried embedding a formula in Javadoc
I tried to write code like a type declaration in Ruby
I made a Ruby extension library in C
I tried to make a parent class of a value object in Ruby
I tried to solve the tribonacci sequence problem in Ruby, with recursion.
I tried using a database connection in Android development
I made a simple calculation problem game in Java
I tried DI with Ruby
I tried to solve the tribonatch sequence problem in Ruby (time limit 10 minutes)
I tried to decorate the simple calendar a little
Creating a calendar using Ruby
I tried to create a Clova skill in Java
Multiplication in a Ruby array
I tried to make a login function in Java
I tried the FizzBuzz problem
I tried Jets (ruby serverless)
I tried metaprogramming in Java
I searched for a web framework with Gem in Ruby
I tried to convert a string to a LocalDate type in Java
I want to create a Parquet file even in Ruby
I tried to implement a buggy web application in Kotlin
I tried to make a client of RESAS-API in Java
I wrote a C parser (like) using PEG in Ruby
Sorting hashes in a Ruby array
Ruby: I made a FizzBuzz program!
Calendar creation problem (fun Ruby practice problem)
I created a PDF in Java.
I tried a little digdag docker.run_options
Implement a gRPC client in Ruby
I tried putting Domino11 in CentOS7
I tried using JWT in Java
I tried to solve the problem of "multi-stage selection" with Ruby
I tried to create a simple map app in Android Studio
I tried to illuminate the Christmas tree in a life game
[Ruby] I want to put an array in a variable. I want to convert to an array
Ruby problem ⑦
I tried to make Numeron which is not good in Ruby
I tried to create an API to get data from a spreadsheet in Ruby (with service account)
I tried using Elasticsearch API in Java
[Ruby] I made a simple Ping client
I tried the new era in Java
Methods that I found useful in Ruby
I tried playing with BottomNavigationView a little ①
I made a risky die with Ruby
I tried the AutoValue library in Intellij
I tried to build Ruby 3.0.0 from source
I tried to build a Firebase application development environment with Docker in 2020
I thought about the best way to create a ValueObject in Ruby
I tried to make full use of the CPU core in Ruby
I tried to make a talk application in Java using AI "A3RT"
[Ruby] I tried to summarize the methods that frequently appear in paiza
[Ruby] I tried to summarize the methods that frequently appear in paiza ②
I tried to make a sample program using the problem of database specialist in Domain Driven Design
[LINE @] I tried to make a Japanese calendar Western calendar conversion BOT [Messaging API]
I made a primality test program in Java
ruby search problem
Escape processing when creating a URL in Ruby
I tried to easily put CentOS-7 in a PC that I no longer need
[For beginners] I tried using DBUnit in Eclipse
[Ruby] FizzBuzz problem