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 Button
s at the top - they are just like that because I didn't copy their ControlTemplate
s):
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
Emulating Int64 Overflows in Ruby
Ruby Before_Validation Triggers Infinite Loop of Call Back
How to Give a Date a Background Color with Axlsx
Receving the Undefined Method 'Generators' Error
How to List All Databases with Activerecord
Heroku: Push Rejected, Failed to Compile Ruby App
Placing Sub Arrays in Neat Rows
How to Handle Partials in an SCSS Project
Twitter API - Ruby Twitter Gem
Rails App Has Trouble with Inter-Model Saving
API Post with Array Using Http Gem (Or Restclient)
Linking to External File in Ruby on Rails
How to Send Notifications to the User Whose Post Received a Comment
Compressed Output Differs from Go to Ruby Implementation