How to Make the Days of the Month Be Printed According to Each Day (Ex: Su Mo Tu We...Etc)

How can I make the days of the month be printed according to each day (ex: Su Mo Tu We...etc)?

The String class in Ruby has a center method:

weekdays = "Su Mo Tu We Th Fr Sa"
month = "#{month_names} #{year}"

output = [
month.center(weekdays.size),
weekdays
].join("\n")

puts output
# April 2015
# Su Mo Tu We Th Fr Sa

The following does not really answer your question. It is just a complete rewrite of your code, because I was bored:

require 'date'

class Month
attr_reader :month, :year

def initialize(month, year)
@month = month
@year = year
end

def first_of_month
Date.new(year, month, 1)
end

def last_of_month
Date.new(year, month, -1)
end

def month_name
last_of_month.strftime('%B')
end

def days_in_month
last_of_month.day
end

def to_s
[].tap do |out|
out << header
out << weekdays

grouped_days.each do |days|
out << days.map { |day| day.to_s.rjust(2) }.join(' ')
end
end.join("\n")
end

private
def header
"#{month_name} #{year}".center(weekdays.size)
end

def weekdays
'Su Mo Tu We Th Fr Sa'
end

def grouped_days
days = (1..days_in_month).to_a
first_of_month.wday.times { days.unshift(nil) }
days.each_slice(7)
end
end

Month.new(4, 2015).to_s
# April 2015
# 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

How can I make the days of the month be printed according to each day (ex: Su Mo Tu We...etc)?

The String class in Ruby has a center method:

weekdays = "Su Mo Tu We Th Fr Sa"
month = "#{month_names} #{year}"

output = [
month.center(weekdays.size),
weekdays
].join("\n")

puts output
# April 2015
# Su Mo Tu We Th Fr Sa

The following does not really answer your question. It is just a complete rewrite of your code, because I was bored:

require 'date'

class Month
attr_reader :month, :year

def initialize(month, year)
@month = month
@year = year
end

def first_of_month
Date.new(year, month, 1)
end

def last_of_month
Date.new(year, month, -1)
end

def month_name
last_of_month.strftime('%B')
end

def days_in_month
last_of_month.day
end

def to_s
[].tap do |out|
out << header
out << weekdays

grouped_days.each do |days|
out << days.map { |day| day.to_s.rjust(2) }.join(' ')
end
end.join("\n")
end

private
def header
"#{month_name} #{year}".center(weekdays.size)
end

def weekdays
'Su Mo Tu We Th Fr Sa'
end

def grouped_days
days = (1..days_in_month).to_a
first_of_month.wday.times { days.unshift(nil) }
days.each_slice(7)
end
end

Month.new(4, 2015).to_s
# April 2015
# 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

What method or class in Ruby can i use to add spaces between each date?

The following should add the spacing you want to each day of the week:

(1..length).each_slice(7) do |week|
output << week.map { |day| day.to_s.rjust(3) }.join
output << "\n"
end

But looking at your expected output, you want to remove the first space of each line. To do so, try this:

(1..length).each_slice(7) do |week|
output << week.map { |day| day.to_s.rjust(3) }.join[1..-1]
output << "\n"
end

Notice the [1..-1] part, this will remove the first character of each week string.

Side note

On a side note, you don't need the explicit return in your methods or the class variables, since you've defined them as attr_reader.

Also, to clean things up a bit you could maybe even refactor the month_names method to something like the code below (note that I've change the method name to month_name). The same could be done to length and even to_s, but that's probably a matter of personal taste.

def month_name
month_names[month - 1]
end

private

def month_names
%w(January February March April May June July August September October November December)
end

Change WPF Calendar control day name format

I've looked into this and unfortunately, I don't think that you will be able to achieve what you want.

To start with, I found the StringFormat to show three character day names in the Custom Date and Time Format Strings page at MSDN:

StringFormat=ddd

Then I thought that you might find a solution for the rest of your problem in the Custom date format for WPF Calendar CalendarItems post. So, adapting the idea from @Quartermeister, I could tried the following:

<Calendar>
<Calendar.CalendarButtonStyle>
<Style TargetType="primitives:CalendarButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="primitives:CalendarButton">
<primitives:CalendarButton>
<TextBlock Text="{Binding Day, StringFormat=ddd}"/>
</primitives:CalendarButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Calendar.CalendarButtonStyle>
</Calendar>

As you can imagine, I was way off because this answered a different problem. So I went back to MSDN to find the default ControlTemplate for the Calendar control to experiment further. If you look at that ControlTemplate, you will see a Style named CalendarItemStyle.

In that Style is a ControlTemplate and in its Resources section, you will see a DataTemplate with the key {x:Static CalendarItem.DayTitleTemplateResourceKey}. Finally, in that DataTemplate, you will see the TextBlock that is responsible for displaying the day names:

<TextBlock Foreground="#FF333333"
FontWeight="Bold"
FontSize="9.5"
FontFamily="Verdana"
Margin="0,6,0,6"
Text="{Binding}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

I increased the size of the day names, so we can be sure that that is the correct TextBlock. (Ignore the odd looking Buttons at the top - they are just like that because I didn't copy their ControlTemplates):

Sample Image

Now if you look at the Binding in that TextBlock, you will see that unfortunately, it is set to {Binding}. This means that it is using the whole data bound value, rather than setting a particular StringFormat on a DateTime object. This means that we cannot use a StringFormat because the data bound value is already a string.

Regex to pick days of the week from a string in Python

The following approach using regular expressions should work:

from itertools import chain
import csv
import re

days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
days_rep = [[day.lower()[:l] for l in xrange(len(day), 0, -1)] for day in days]
days_rep = sorted(chain.from_iterable([(len(day), day, index) for day in days] for index, days in enumerate(days_rep)), reverse=True)
days_d = {day : ' {} '.format(days[value]) for length, day, value in days_rep}
re_days = re.compile(r'({})'.format('|'.join(day for length, day, value in days_rep)), flags=re.I)

def normalise(entry):
to_days = re_days.sub(lambda x: days_d[x.group(1).lower()], entry)
return to_days.replace(' ', ' ').replace(' - ', '-').strip()

with open('input.csv', 'rb') as f_input:
for cols in csv.reader(f_input):
print "{} {} {}".format(cols[0], normalise(cols[1]), cols[2])

This assumes you have a csv file that looks as follows:

XYZ,Mon-FR,ABC
XY,Mo-Fr,AB
Xy,M-F,AbC
xyz,MON-FRI,ABC
XYZ,Mon-Su,ABC
XYZ,Sat-Sun,ABC
XXX,SaSu,ABC
XY,MF & Sa,ABC

It will display the following output:

XYZ Monday-Friday ABC
XY Monday-Friday AB
Xy Monday-Friday AbC
xyz Monday-Friday ABC
XYZ Monday-Sunday ABC
XYZ Saturday-Sunday ABC
XXX Saturday Sunday ABC
XY Monday Friday & Saturday ABC

The script works by first building a regular expression based on the days of the week in length order, starting as follows:

(wednesday|wednesda|thursday| .... mond|frid|wed|tue|thu|sun|sat|mon|fri|we|tu|th|su|sa|mo|fr|w|t|t|s|s|m|f)

This is used to lookup the corresponding full text in a dictionary. Lastly the formatting is fixed to remove extra spacing.



Related Topics



Leave a reply



Submit