"let" in rspec doesn't write to database - ruby-on-rails

The below does not write to my database so my tests fail:
let(:level_1) { Fabricate(:level, number: 1, points: 100) }
let(:level_2) { Fabricate(:level, number: 2, points: 200) }
Level.count # 0
However, the following does work
before do
level_1 = Fabricate(:level, points: 100, number: 1)
level_2 = Fabricate(:level, points: 200, number: 2)
end
Level.count # 2
This seems very strange.

Its because let is lazily-loaded. Meaning, only when you invoke level1 and level2(inside the examples), the blocks will be executed and the records will be created. A workaround is to use let! which is invoked before each example.
Try
let!(:level_1) { Fabricate(:level, number: 1, points: 100) }
let!(:level_2) { Fabricate(:level, number: 2, points: 200) }
Now, Level.count will return 2
For more, see https://www.relishapp.com/rspec/rspec-core/v/2-5/docs/helper-methods/let-and-let

Related

How can i find sum of three element in a given away

Is there a method we use to reach the desired number in an array given in dart language.. I can do this for binary ones, but I can't do it for a code that finds the sum of 3 or more elements
For example
Input: candidates = [10,1,2,7,6,1,5], target = 8
Output:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
this is the my code i have done until now
void main() {
var candidates = [10, 1, 2, 7, 6, 1, 5], target = 8;
var answer = [];
for (int i = 0; i < candidates.length; i++) {
for (int j = 0; j < candidates.length; j++) {
if (candidates[i] + candidates[j] == target && i != j && i < j) {
answer.add([candidates[i], candidates[j]]);
}
}
}
}
I am sure this can be done more efficient but since the solution is for some Leetcode assignment, I don't really want to spend too much time on optimizations.
I have tried added some comments in the code which explains my way of doing it:
void main() {
getSumLists([10, 1, 2, 7, 6, 1, 5], 8).forEach(print);
// [5, 1, 2]
// [1, 6, 1]
// [1, 7]
// [6, 2]
getSumLists([2, 5, 2, 1, 2], 5).forEach(print);
// [2, 1, 2]
// [5]
}
Iterable<List<int>> getSumLists(
List<int> candidates,
int target, {
List<int>? tempAnswer,
int sum = 0,
}) sync* {
// We cannot use default value in parameter since that makes list const
final tempAnswerNullChecked = tempAnswer ?? [];
if (sum == target) {
// We got a result we can return.
// OPTIMIZATION: If you know the returned list from each found result is not
// being used between found results, you can remove the `.toList()` part.
yield tempAnswerNullChecked.toList();
} else if (sum > target) {
// No need to search further in this branch since we are over the target
return;
}
// Make a copy so we don't destroy the input list but also so it works even
// if provided list as input is non-growing / non-modifiable
final newCandidates = candidates.toList();
while (newCandidates.isNotEmpty) {
// We take numbers from the end of the list since that is more efficient.
final number = newCandidates.removeLast();
// Recursive call where we return all results we are going to find given
// the new parameters
yield* getSumLists(
newCandidates,
target,
tempAnswer: tempAnswerNullChecked..add(number),
sum: sum + number,
);
// Instead of creating a new tempAnswerNullChecked, we just reuse it and
// make sure we remove any value we are temporary adding
tempAnswerNullChecked.removeLast();
// Ensure we don't get duplicate combinations. So if we have checked the
// number `1` we remove all `1` so we don't try the second `1`.
newCandidates.removeWhere((element) => element == number);
}
}

LUA and table data - finding data in a nested loop

I have the following table
scavenging =
{
{
type = "Greenskin|16",
fast_levelup = 20, --Number of levels with 75% chance to level up after required level
normal_levelup = 40, --Number of levels with 50% chance to level up after fast_levelup + required level
slow_levelup = 40, --Number of levels with 25% chance
drops = --Drops
{
{items = {"Linen", "Bolt of Linen", "Coarse Thread", "Feather", "Cotton"}, droprates = {60, 10, 10, 10, 2}},
},
},
}
This is one data value in a series. I use
function scavenge_meta(scavenge_name)
for _, meta in pairs(scavenging) do
if string.match(meta.type, scavenge_name) then
return meta
end
end
end
to pull the needed data. The question is, is there an easy way to get to the droprates value without having to do a few for (pairs)? Right now for example I can use:
local founditem = scavenge_meta("Greenskin|16")
And this works, and then I can use founditem.fast_levelup etc. I was hoping to access the drops table with founditem.drops.items for example, but this doesn't work, I need to do a pairs(founditem.drops) then pairs(valuefound.items) /etc.
Maybe there is a better way of doing this?
if you can change the table then do:
scavenging =
{
["Greenskin|16"] = {
type = "Greenskin|16",
fast_levelup = 20,
normal_levelup = 40,
slow_levelup = 40,
drops =
{
{items = {"Linen", "Bolt of Linen", "Coarse Thread", "Feather", "Cotton"}, droprates = {60, 10, 10, 10, 2}},
},
},
}
and get data directly by index
print(scavenging["Greenskin|16"].fast_levelup)
otherwise, just by searching as you did.

Observable distinctUntilChanged returns duplicates

Setup: RxSwift 4.2 Swift 4.1 Xcode 9.4.1
I'm currently using distinctUntilChanged to get unique values.
But in my case it's only working for "sorted" values.
Like for example here:
func unique(source: Observable<Int>) -> Observable<Int> {
return source.distinctUntilChanged()
}
Here is the corresponding test:
func testUnique() {
let input = Observable.from([1,2,3,4,4,5,4])
let expectation = [Recorded.next(0, 1),
Recorded.next(0, 2),
Recorded.next(0, 3),
Recorded.next(0, 4),
Recorded.next(0, 5),
Recorded.completed(0)]
_ = Class().unique(source: input).subscribe(observer)
XCTAssertEqual(observer.events, expectation)
}
And my test is failing with:
XCTAssertEqual failed: ("[next(1) # 0, next(2) # 0, next(3) # 0, next(4) # 0, next(5) # 0, next(4) # 0, completed # 0]")
is not equal to ("[next(1) # 0, next(2) # 0, next(3) # 0, next(4) # 0, next(5) # 0, completed # 0]") -
So the last 4 is a duplicate.
Is this behavior expected or a bug?
It is indeed expected behaviour, that is why operator is called '.distinctUntilChanged()'. What you apparently want is '.distinct()', but it is not available in basic 'RxSwift' framework, only in 'RxSwiftExt' framework - https://github.com/RxSwiftCommunity/RxSwiftExt#distinct
This is expected behaviour. distinctUntilChanged is comparing with the previous value in the stream, in your case it should emit:
let expectation = [Recorded.next(0, 1),
Recorded.next(0, 2),
Recorded.next(0, 3),
Recorded.next(0, 4),
Recorded.next(0, 5),
Recorded.next(0, 4),
Recorded.completed(0)]
Think you can use scan to remember previous values and then just check if it needs to emit new value. Here's a quick solution using scan:
extension Observable where Element: Equatable {
func unique() -> Observable<Element> {
return scan([Element](), accumulator: { previousValues, nextValue in
if !previousValues.contains(nextValue) {
return previousValues + [nextValue]
}
return previousValues
})
.distinctUntilChanged()
.map { $0.last! }
}
}
I made up a simple type specifiy answer myself.
It's basicly the RxSwiftExt distinct solution:
func unique(source: Observable<Int>) -> Observable<Int> {
var cache = Set<Int>()
return source.flatMap { element -> Observable<Int> in
if cache.contains(element) {
return Observable<Int>.empty()
} else {
cache.insert(element)
return Observable<Int>.just(element)
}
}
}

AudioKit 4.0 AKPeriodicFunctions Not Starting

Unable to start AK4 AKPeriodic function in XCode 9. In the following excerpt from the "Plucked String" playground, I inserted two log messages to help identify processing events. I never see the "periodic function startup" message in the console log. All I hear is a very short clicking sound.
let scale = [0, 2, 4, 5, 7, 9, 11, 12]
let performance = AKPeriodicFunction(frequency: playRate) {
print("periodic function startup")
var note = scale.randomElement()
let octave = [2, 3, 4, 5].randomElement() * 12
if random(0, 10) < 1.0 { note += 1 }
if !scale.contains(note % 12) { print("ACCIDENT!") }
let frequency = (note + octave).midiNoteToFrequency()
if random(0, 6) > 1.0 {
pluckedString.trigger(frequency: frequency)
}
}
AudioKit.output = reverb
AudioKit.start(withPeriodicFunctions: performance)
print("AK startup")
performance.start()
This is fixed in the develop branch, as per this issue:
https://github.com/AudioKit/AudioKit/issues/1066

Difficult couchdb query

I have the following query:
view.reduce.group_level(5).keys
which returns:
[["1f9c79a33f399a7937d880c5f31e8dbc", 2011, 12, 29, 13], ["1f9c79a33f399a7937d880c5f31e8dbc", 2011, 12, 29, 14], ["c38332ffc275b6c70bcf06ffc39ddbdd", 2011, 12, 29, 13], ["c38332ffc275b6c70bcf06ffc39ddbdd", 2011, 12, 29, 14]]
The first key is an id and the other keys are year, month, day, hour
I would like all the rows between 2010 and 2013. So I want to ignore the first key.
The problem is that i need to set the first parameter to get the results but i want to get all the results for all the keys.
for example: view.reduce.group_level(5).startkey(["every_possible_key", 2010]).endkey(['every_possible_key", 2013, {}])
If i leave the first key blank than i get nothing. If i give it "\u9999" than i get everything and it ignores the 2nd key.
Somebody knows what I am doing wrong?
Thanks a lot.
map:
function(d) {
if (d['type'] == 'State' && d['driver_id'] && d['name'] && d['created_at']) {
var dt = new Date(d.created_at);
emit([d.driver_id, dt.getFullYear(), dt.getMonth() + 1, dt.getDate(), dt.getHours()], d.name);
}
}
reduce:
function(k,v,r) {
var result = {
'hire': 0, 'hired': 0, 'arrived': 0, 'pick up': 0, 'drop off': 0,
'missed': 0, 'rider cancel': 0, 'driver cancel': 0, 'no show': 0,
'avail': 0, 'unavail': 0, 'other': 0
};
if (r) {
var row = null;
for (i in v) {
row = v[i];
for (j in row) {
result[j] += row[j];
}
}
} else {
for (i in v) {
if (result[v[i]] != null) {
result[v[i]] += 1;
} else {
result['other'] += 1;
}
}
}
return result;
}
What you're "doing wrong" is to use a key you don't need in your query as the first key of your view.
If you need it for another query, create another view.

Resources