How to Make :Level Change Based on :Committed Days

How to Add :committed Days to :levels?

Assuming committed is a field containing an array of day names (e.g. ['Monday', 'Friday'], the following should work:

committed_wdays = committed..map { |day| Date::DAYNAMES.index(day) }
n_days = (date_started..Date.today).count { |date| committed_wdays.include? date.wday }

How to restart current_level for every third missed_day (3 strikes you're out!)?

Here is my solution:

You need to keep track the days you lost at the moment you get 3 missed days (you need to add a field in level):

migration file.rb

class AddDaysLostToLevels < ActiveRecord::Migration
def change
add_column :levels, :days_lost, :integer, default: 0
end

end

Then change controller days_missed to reset when you get 3 missed days and store the days you lost when you start again level (in the variable days_lost):

class DaysMissedController < ApplicationController

def create
habit = Habit.find(params[:habit_id])
habit.missed_days = habit.missed_days + 1
habit.save!
level = habit.levels.find(params[:level_id])
level.missed_days = level.missed_days + 1
if level.missed_days == 3
level.missed_days = 0
level.days_lost += habit.calculate_days_lost + 1
end
...remain the same

Now we need to define "calculate_days_lost" and "real_missed_days" methods in habit.rb.

Remember to use self.real_missed_days instead self.missed_days in current_level method: (they are diferent because you can start again a level). New habit.rb will be like this:

class Habit < ActiveRecord::Base
belongs_to :user
has_many :comments, as: :commentable
has_many :levels
serialize :committed, Array
validates :date_started, presence: true
before_save :current_level
acts_as_taggable
scope :private_submit, -> { where(private_submit: true) }
scope :public_submit, -> { where(private_submit: false) }

attr_accessor :missed_one, :missed_two, :missed_three

def save_with_current_level
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.save
end

def self.committed_for_today
today_name = Date::DAYNAMES[Date.today.wday].downcase
ids = all.select { |h| h.committed.include? today_name }.map(&:id)
where(id: ids)
end

def current_level_strike
levels[current_level - 1] # remember arrays indexes start at 0
end

def real_missed_days
value = 0
levels.each do |level|
if level.missed_days != nil
value += level.missed_days + level.days_lost
end
end
value
end

def committed_wdays
committed.map do |day|
Date::DAYNAMES.index(day.titleize)
end
end

def n_days
((date_started.to_date)..Date.today).count do |date|
committed_wdays.include? date.wday
end - self.real_missed_days
end

def calculate_days_lost
case n_days
when 0..9
n_days
when 10..24
n_days-10
when 25..44
n_days-25
when 45..69
n_days-45
when 70..99
n_days-70
else
n_days-100
end
end

def current_level
return 0 unless date_started
case n_days
when 0..9
1
when 10..24
2
when 25..44
3
when 45..69
4
when 70..99
5
else
6
end
end

end

How do I make a Git commit in the past?

The advice you were given is flawed. Unconditionally setting GIT_AUTHOR_DATE in an --env-filter would rewrite the date of every commit. Also, it would be unusual to use git commit inside --index-filter.

You are dealing with multiple, independent problems here.

Specifying Dates Other Than “now”

Each commit has two dates: the author date and the committer date. You can override each by supplying values through the environment variables GIT_AUTHOR_DATE and GIT_COMMITTER_DATE for any command that writes a new commit. See “Date Formats” in git-commit(1) or the below:

Git internal format = <unix timestamp> <time zone offset>, e.g.  1112926393 +0200
RFC 2822 = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601 = e.g. 2005-04-07T22:13:13

The only command that writes a new commit during normal use is git commit. It also has a --date option that lets you directly specify the author date. Your anticipated usage includes git filter-branch --env-filter also uses the environment variables mentioned above (these are part of the “env” after which the option is named; see “Options” in git-filter-branch(1) and the underlying “plumbing” command git-commit-tree(1).

Inserting a File Into a Single ref History

If your repository is very simple (i.e. you only have a single branch, no tags), then you can probably use git rebase to do the work.

In the following commands, use the object name (SHA-1 hash) of the commit instead of “A”.
Do not forget to use one of the “date override” methods when you run git commit.

---A---B---C---o---o---o   master

git checkout master
git checkout A~0
git add path/to/file
git commit --date='whenever'
git tag ,new-commit -m'delete me later'
git checkout -
git rebase --onto ,new-commit A
git tag -d ,new-commit

---A---N (was ",new-commit", but we delete the tag)
\
B'---C'---o---o---o master

If you wanted to update A to include the new file (instead of creating a new commit where it was added), then use git commit --amend instead of git commit. The result would look like this:

---A'---B'---C'---o---o---o   master

The above works as long as you can name the commit that should be the parent of your new commit. If you actually want your new file to be added via a new root commit (no parents), then you need something a bit different:

B---C---o---o---o   master

git checkout master
git checkout --orphan new-root
git rm -rf .
git add path/to/file
GIT_AUTHOR_DATE='whenever' git commit
git checkout -
git rebase --root --onto new-root
git branch -d new-root

N (was new-root, but we deleted it)
\
B'---C'---o---o---o master

git checkout --orphan is relatively new (Git 1.7.2), but there are other ways of doing the same thing that work on older versions of Git.

Inserting a File Into a Multi-ref History

If your repository is more complex (i.e. it has more than one ref (branches, tags, etc.)), then you will probably need to use git filter-branch. Before using git filter-branch, you should make a backup copy of your entire repository. A simple tar archive of your entire working tree (including the .git directory) is sufficient. git filter-branch does make backup refs, but it is often easier to recover from a not-quite-right filtering by just deleting your .git directory and restoring it from your backup.

Note: The examples below use the lower-level command git update-index --add instead of git add. You could use git add, but you would first need to copy the file from some external location to the expected path (--index-filter runs its command in a temporary GIT_WORK_TREE that is empty).

If you want your new file to be added to every existing commit, then you can do this:

new_file=$(git hash-object -w path/to/file)
git filter-branch \
--index-filter \
'git update-index --add --cacheinfo 100644 '"$new_file"' path/to/file' \
--tag-name-filter cat \
-- --all
git reset --hard

I do not really see any reason to change the dates of the existing commits with --env-filter 'GIT_AUTHOR_DATE=…'. If you did use it, you would have make it conditional so that it would rewrite the date for every commit.

If you want your new file to appear only in the commits after some existing commit (“A”), then you can do this:

file_path=path/to/file
before_commit=$(git rev-parse --verify A)
file_blob=$(git hash-object -w "$file_path")
git filter-branch \
--index-filter '

if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$before_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi

' \
--tag-name-filter cat \
-- --all
git reset --hard

If you want the file to be added via a new commit that is to be inserted into the middle of your history, then you will need to generate the new commit prior to using git filter-branch and add --parent-filter to git filter-branch:

file_path=path/to/file
before_commit=$(git rev-parse --verify A)

git checkout master
git checkout "$before_commit"
git add "$file_path"
git commit --date='whenever'
new_commit=$(git rev-parse --verify HEAD)
file_blob=$(git rev-parse --verify HEAD:"$file_path")
git checkout -

git filter-branch \
--parent-filter "sed -e s/$before_commit/$new_commit/g" \
--index-filter '

if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$new_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi

' \
--tag-name-filter cat \
-- --all
git reset --hard

You could also arrange for the file to be first added in a new root commit: create your new root commit via the “orphan” method from the git rebase section (capture it in new_commit), use the unconditional --index-filter, and a --parent-filter like "sed -e \"s/^$/-p $new_commit/\"".

undefined method `each_with_index' for 0:Fixnum

When you try to load the new template you are getting this error because @habit.levels is returning 0 rather than an enumerable object. Since you can't iterate over a Fixnum, the exception is being thrown when it gets to the .each_with_index call. Check out this line in your code:

def levels
return 0 unless date_started
...
end

It looks like you're validating the presence of date_started but with this @habit the #levels method is returning 0.

As ilan berci points out, this line is always going to fail when chained with .each_with_index because it is named levels but returns a Fixnum. Looking back at the top of your model, however, you've already declared has many :levels up there, which generates its own levels method that will gather all the levels associated with the given @habit and return them as an enumerable object .

It sounds like that's what you were expecting to happen based on the use of each_with_index, but when you declared the other levels method further down in the model, it overrides the method given to you by the has_many :levels line. If you really do need to iterate over a collection of a habit's levels, you should change the name of the custom levels method that is now designed to return a Fixnum based on the value of n_days.

Creating a Calculated Time Periods Hierarchy

I've just created the same this way:

1) Add dummy attribute for unfiltered values with the name 'All Time'
(key is int with 0 value)

2) Add 3 empty members

CREATE MEMBER CURRENTCUBE.[Report Date].[Time Period].[All].[Last 30 Days]
AS
null,
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Report Date].[Time Period].[All].[Last 60 Days]
AS
null,
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Report Date].[Time Period].[All].[Last 90 Days]
AS
null,
VISIBLE = 1;

3) Than add scopes (I have another key format):

/* SCOPES */
SCOPE ([Report Date].[Time Period].[All].[Last 30 Days]);
THIS = Sum(LastPeriods(30,StrToMember("[Report Date].[Report Date].[Day].&["+CStr(Format(Now(),"yyyyMMdd"))+"]")));
END SCOPE;
SCOPE ([Report Date].[Time Period].[All].[Last 60 Days]);
THIS = Sum(LastPeriods(60,StrToMember("[Report Date].[Report Date].[Day].&["+CStr(Format(Now(),"yyyyMMdd"))+"]")));
END SCOPE;
SCOPE ([Report Date].[Time Period].[All].[Last 90 Days]);
THIS = Sum(LastPeriods(90,StrToMember("[Report Date].[Report Date].[Day].&["+CStr(Format(Now(),"yyyyMMdd"))+"]")));
END SCOPE;

It works (also add a measure to count members of a level to validate):

LastNDays

How can i change the position of the days(number) in tkcalendar

There is no option to change the position of the day numbers. Therefore, it is necessary to dig into the source code of the widget to do it. The days are just labels so it is possible get the desired position by setting their anchor option to "nw". They are stored into a list of lists called ._calendar (one list per week):

import tkinter as tk
from tkcalendar import Calendar

class MyCalendar(Calendar):
def __init__(self, master, **kw):
Calendar.__init__(self, master, **kw)

for row in self._calendar:
for label in row:
label['anchor'] = "nw"

# # uncomment this block to align left weekday names
# for label in self._week_days:
# label['anchor'] = "w"

root = tk.Tk()
cal = MyCalendar(root, showweeknumbers=False)
cal.pack(fill='both', expand=True)
root.geometry("400x300")
root.mainloop()

screenshot

git revert back to certain commit

git reset --hard 4a155e5 Will move the HEAD back to where you want to be. There may be other references ahead of that time that you would need to remove if you don't want anything to point to the history you just deleted.



Related Topics



Leave a reply



Submit