R6 classes, cloning, and a simple way of modifying the elements of the nested R6 object - r

I am developing a structure of R6 classes. The idea is to have a big R6 class collecting many small objects of other R6 class types. The big object is the input to a function.
The point is that I would like to make it simple for users to modify the small objects within the big by developing R6 methods in the public object that would facilitate this.
Let me explain on the following example:
ClassOne object is one of the small objects:
> ClassOne = R6::R6Class(
+ "ClassOne",
+
+ public = list(
+ element = numeric(),
+
+ initialize = function() {
+ self$element <- 1
+ },
+
+ set_element = function(value) {
+ if (!missing(value)) {
+ self$element <- value
+ }
+ }
+
+ )
+ )
ClassTwo object is the big object that contains as self$class_one_element an object of class ClassOne.
> ClassTwo = R6::R6Class(
+ "ClassTwo",
+
+ public = list(
+
+ class_one_element = list(),
+
+ initialize = function() {
+ self$class_one_element = ClassOne$new()
+ },
+
+ get_class_one = function() {
+ self$class_one_element$clone()
+ }
+ )
+ )
Once the ClassTwo object is initiated:
> ct = ClassTwo$new()
> ct$class_one_element$element
[1] 1
the method get_class_one is cloning the whole self$class_one_element:
> ct_co = ct$get_class_one()
The method set_element is used to modify the small object:
> ct_co$set_element(2)
> ct_co$element
[1] 2
but despite the application of deep cloning, this operation is modifying only the element in the small object ct_co and not the corresponding element in the big object:
> ct$class_one_element$element
[1] 1
THE QUESTION: How to rewrite the ClassTwo (I guess) so that the sequence:
> ct = ClassTwo$new()
> ct_co = ct$get_class_one()
> ct_co$set_element(2)
is modifying ct$class_one_element$element as well?
I would greatly appreciate your suggestions!

Related

How to treat prefixed keywords?

I have following parsing problem. My keywords can be prefixed with an underscore for deactivation of the option, block etc.
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore
test_string = r'''
keyword1list {
keyword1 {
option 213
}
_keyword1 {
option 214
}
}
'''
This can happen to any keyword, here keyword1list, keyword1 or option. What I like to achieve is to either leave those blocks out during parsing or parse them but catch the deactivation prefix.
Currently, I can successfully parse the "activated" test_string with the following code, but it fails for apparent reasons with the underscored keyword.
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = Keyword('keyword1') + lparent
kw1_block = kw1_block + Keyword('option') + pyparsing_common.number.setResultsName('option')
kw1_block = Group(kw1_block + rparent).setResultsName('keyw1')
kw2_block = Keyword('keyword1list') + lparent
kw2_block = kw2_block+ OneOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list', listAllMatches=True)
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\\n'))
print tmp[0]
My current solution is, to put all keywords in a list and set up a dictionary to combine them all with the underscore and give them a flag.
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore, ZeroOrMore
test_string = r'''
keyword1list {
_keyword1 {
option 1
}
keyword1 {
option 2
}
_keyword1 {
option 3
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}
'''
kwlist = ['keyword1', 'keyword1list', 'option']
keywords = {}
for k in kwlist:
keywords[k] = Keyword('_' + k).setResultsName('deactivated') | Keyword(
k).setResultsName('activated')
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = keywords['keyword1'] + lparent
kw1_block = kw1_block + keywords[
'option'] + pyparsing_common.number.setResultsName('option') + rparent
kw1_block = Group(kw1_block).setResultsName('keyword1', listAllMatches=True)
kw2_block = keywords['keyword1list'] + lparent
kw2_block = kw2_block + ZeroOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list')
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\\n'))
print tmp[0]
While this allows to parse everything properly I have to recreate the logic afterwards (finding the deactivated keywords and drop them from the result), which I like to avoid. I believe I need a parseAction on the underscored keywords to drop those tokens somehow but I currently cannot figure out how to do this.
Any help is greatly appreciated.
When I see a parser that is intended for filtering out selected blocks of text, my first approach is usually to write a parser that will match just the selected part, and then use transformString with a suppressed form of that parser:
kwlist = ['keyword1', 'keyword1list', 'option']
to_suppress = MatchFirst(Keyword('_' + k) for k in kwlist)
kw_body = nestedExpr("{", "}") | Word(nums)
filter = (to_suppress + kw_body).suppress()
print(filter.transformString(test_string))
Running this with your test string gives:
keyword1list {
keyword1 {
option 2
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}

Trouble with a function in R, "BinHist"

I'm trying to use a bit of code that I found in an academic journal (). I'm new-ish to R. I keep getting an error when I reach the code calling up the function "binHist" that says "could not find the function "binhist". I can't figure out if it's in a library/ package I need to install or if there's another problem with the code. Any help would be much appreciated. Here's the code I extracted from the article:
whichData = yourData
baseH = data.frame()
RunningSum = 0
for (i in 2:16) {
tempBin = NULL
tempBin = binhist(i, whichData$rt)
theMean = sum(tempBin)/(i)
Divisor = sum(tempBin)
new = data.frame()
for (j in 1:ncol(tempBin)) {
grabVal = (tempBin[j] - theMean)^2
names(grabVal) <- NULL
new = c(new,grabVal)
}
extra = i - ncol(tempBin)
NewSum = Reduce("+",new) + extra*((0 - theMean)^2)
StdDev = sqrt(NewSum /(i-1))
RowVal = StdDev /Divisor
RunningSum = RunningSum + RowVal
baseH = c(baseH, list(tempBin))
}
paste("Number of Trials:",Divisor)
paste("Modulo-Binning Score (MBS): ",RunningSum)
library(plyr)
baseNow = do.call(rbind.fill,baseH)

Reference class fields disappearing

I decided to give Reference Classes another shot, but my first hello world is already giving me issues. What is going wrong here?
> memory <- setRefClass(
+ Class = "memory",
+ fields = list(state="vector"),
+ methods = list(
+ get = function() { return(state) },
+ set = function(x) { state <<- x }
+ )
+ )$new()
> memory$set(123)
> print(memory)
Reference class object of class "memory"
Field "state":
[1] 123
> memory$get()
[1] 123
> print(memory)
Reference class object of class "memory"
Field "state":
Error in methods::show(field(fi)) :
error in evaluating the argument 'object' in selecting a method for function 'show': Error in get(name, envir = .self) :
unused argument(s) (name, envir = .self)
I'm not very experienced with Reference Classes but according to the help page (?ReferenceClasses), I think that you have to add a show method to your class to be able to print automaticaly your object.
memory <- setRefClass(
Class = "memory",
fields = list(state="vector"),
methods = list(
get = function() { return(state) },
set = function(x) { state <<- x },
show = function() {methods::show(state)}
)
)$new()
memory$set(123)
print(memory)
#[1] 123
memory$get()
#[1] 123
print(memory)
#[1] 123
Hope this help

queries in entity framework

i have to fetch those records where cityname like'zipcode' where zipcode is variable and apply conditions
var zipcd = (from u in db.ZipCodes1
where u.CityName.Contains(zipcode) && u.CityType == "D"
select u).ToList().Select(u => new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
stateabbr = u.StateAbbr
}).Distinct();
Viewsearch vs = (Viewsearch)zipcd;
if (zipcd.Count() > 1)
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName;
}
else if (locations == "")
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName;
}
else
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName + "," + locations;
}
if (zipcd.Count() > 3) is greater than 3
{
locations = locations.Replace(locations, "," + "<br>");
}
The problem is that you're casting an iterator to the type of a single element on the line
ViewSearch vs = (ViewSearch)zipcd.
If you want vs to be a single object, you must call First() or FirstOrDefault() on your collection:
ViewSearch vs = zipcd.First(); // Throws if there are no elements
ViewSearch vs = zipcd.FirstOrDefault(); // null if there are no elements
First of all I would suggest that you download and use the lovely LINQPad not only to run your LINQ queries first but also to learn from it (has a lot of samples that you can run right form there, no more config needed)
for your question:
var zipcd = (
from u in db.ZipCodes1
where u.CityName.Contains(zipcode) && u.CityType == "D"
select new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
stateabbr = u.StateAbbr
}).Distinct().ToList();
As you can see the query works:
Distinct at the end of your query uses IEqualityComparer, and I'm guessing you haven't defined one for Viewsearch. It would look something like this:
public class ViewsearchComparer : IEqualityComparer<Viewsearch>
{
public bool Equals(Viewsearch vs1, Viewsearch vs2)
{
// Implementation
}
public int GetHashCode(Viewsearch vs)
{
// Implementation
}
}
After you have that defined, you pass it into your distinct call:
.Select(u => new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
Stateabbr = u.StateAbbr
})
.Distinct(new ViewsearchComparer());

LINQ to SQL Ordering from external method

It seem to me that this was hard...
var MostRated = (from p in db.Posts
let AverageRating = CalculateAverageRatingFromPost(p)
where p.PostStatus == Convert.ToInt32(PostStatusEnum.Published.Value) && p.IsDeleted == false
orderby p.PublishedDate descending
select new
{
PostUrl = Common.PostUrl(p.Section.Name, p.Permalink),
Title = Common.TrimString(p.Title, 50),
Excerpt = Common.TrimString(p.Excerpt, 80),
AverageRate = CalculateAverageRating((from pr in db.Ratings
where pr.ObjectType == Convert.ToInt32(ObjectTypeEnum.Post.Value) && pr.ObjectID == p.ID
select pr).SingleOrDefault()),
PublishedDate = new DateHelper().DateTimeInWords(p.PublishedDate.Value)
}).OrderByDescending(o => o.AverageRate).Take(5).ToList();
and the other method is
private Decimal CalculateAverageRating(Rating pr)
{
if (pr != null)
{
Decimal Average = ((1 * (Decimal)pr.Star1) + (2 * (Decimal)pr.Star2) + (3 * (Decimal)pr.Star3) + (4 * (Decimal)pr.Star4) + (5 * (Decimal)pr.Star5)) / ((Decimal)pr.Star1 + (Decimal)pr.Star2 + (Decimal)pr.Star3 + (Decimal)pr.Star4 + (Decimal)pr.Star5);
return Average;
}
else
{
return 0;
}
}
I get this run time error "no supported translation to SQL".
What i want is to get lists of the posts, and do a small quick calculations of the rating and then sort those from highest to low and take 5 posts only.
Thanks
I haven't tested this, but try defining the function as an Expression object.
Expression<Rating, Decimal> CalculateAverageRating =
pr => (Decimal)(
pr == null ? 0 :
(pr.Star1 + 2*pr.Star2 + 3*pr.Star3 + 4*pr.Star4 + 5*pr.Star5)
/(pr.Star1 + pr.Star2 + pr.Star3 + pr.Star4 + pr.Star5));

Resources