Funnels and RethinkDB - rethinkdb

I have some steps saved in RethinkDB like this :
{
date: "Sat Feb 06 2015 00:00:00 GMT+00:00",
step: 1
},
{
date: "Sat Feb 06 2015 11:11:11 GMT+00:00",
step: 3
},
{
date: "Sat Feb 06 2015 22:22:22 GMT+00:00",
step: 2
}
I'd like to count the number of steps done in order 1, 2, 3.
So for this example, I'd like to get something like this :
{
step_1: 1,
step_2: 1,
step_3: 0
}
I have seen a step 1, so step_1 is 1
I have seen a step 2, and have seen a step 1 before, so step_2 is 1
I have seen a step 3, but I haven't seen a step 2 before, so step_3 is 0
I've tried a lot of things but didn't find a way to do it and actually I'm not really sure it's possible with RethinkDB.
Any of you have an idea for me ?
Thanks,
Adrien

As a preface: this really abuses the r.js term, and so is always going to be a bit slow. So this solution is not really great for production services. Unless someone comes up with a better answer (i.e.: all ReQL) it would be better to do this mostly client-side, possibly using a group and min to pre-digest some of this.
A couple of us really think that there is an answer, and mine uses reduce with a JavaScript function for the main bit. Unfortunately in working on this answer I found a bug that crashes our server, so for the moment my answer is slightly untested, and not recommended, but the in-progres version might give you the start of an answer:
r.table('alpha').reduce(r.js('''(
function(left, right) {
var returnValue = [];
var sources = [left, right];
for (var i in sources) {
var source = sources[i];
if (source.date) {
if (!returnValue[source.step] || returnValue[source.step] > source.date) {
returnValue[source.step] = source.date;
}
} else {
for (i in source) {
if (!returnValue[i] || returnValue[i] > source(key)) {
returnValue[i] = source(key);
}
}
}
}
return returnValue;
})''')).map(r.js('''(
function (row) {
var allValid = true;
var lastDate = 0;
var returnValue = [];
for (i in row) {
var afterLast = row[i] && row[i] > lastDate && allValid;
allValid = afterLast == true;
returnValue.push(afterLast);
lastDate = row[i];
}
}
})''')).run()

Related

Getting non overlapping between two dates with Carbon

UseCase: Admin assigns tasks to People. Before we assign them we can see their tasks in a gantt chart. According to the task assign date and deadline, conflict days (overlap days) are generated between tasks.
I wrote this function to get overlapping dates between two dates. But now I need to get non overlapping days between two dates, below is the function I wrote.
$tasks = Assign_review_tasks::where('assigned_to', $employee)
->where('is_active', \Constants::$REVIEW_ACTIVE)
->whereNotNull('permit_id')->get();
$obj['task'] = count($tasks);
// count($tasks));
if (count($tasks) > 0) {
if (count($tasks) > 1) {
$start_one = $tasks[count($tasks) - 1]->start_date;
$end_one = $tasks[count($tasks) - 1]->end_date;
$end_two = $tasks[count($tasks) - 2]->end_date;
$start_two = $tasks[count($tasks) - 2]->start_date;
if ($start_one <= $end_two && $end_one >= $start_two) { //If the dates overlap
$obj['day'] = Carbon::parse(min($end_one, $end_two))->diff(Carbon::parse(max($start_two, $start_one)))->days + 1; //return how many days overlap
} else {
$obj['day'] = 0;
}
// $arr[] = $obj;
} else {
$obj['day'] = 0;
}
} else {
$obj['day'] = 0;
}
$arr[] = $obj;
start_date and end_date are taken from database,
I tried modifying it to,
(Carbon::parse((min($end_one, $end_two))->add(Carbon::parse(max($start_two, $start_one))))->days)->diff(Carbon::parse(min($end_one, $end_two))->diff(Carbon::parse(max($start_two, $start_one)))->days + 1);
But it didn't work, in simple terms this is what I want,
Non conflicting days = (end1-start1 + end2-start2)- Current overlapping days
I'm having trouble translate this expression . Could you help me? Thanks in advance
before trying to reimplement complex stuff I recommend you take a look at enhanced-period for Carbon
composer require cmixin/enhanced-period
CarbonPeriod::diff macro method is what I think you're looking for:
use Carbon\CarbonPeriod;
use Cmixin\EnhancedPeriod;
CarbonPeriod::mixin(EnhancedPeriod::class);
$a = CarbonPeriod::create('2018-01-01', '2018-01-31');
$b = CarbonPeriod::create('2018-02-10', '2018-02-20');
$c = CarbonPeriod::create('2018-02-11', '2018-03-31');
$current = CarbonPeriod::create('2018-01-20', '2018-03-15');
foreach ($current->diff($a, $b, $c) as $period) {
foreach ($period as $day) {
echo $day . "\n";
}
}
This will output all the days that are in $current but not in any of the other periods. (E.g. non-conflicting days)

Is there better way to improve my algorithm of finding drawdown in stock market?

I am trying to calculate drawdowns of every stock.
Definition of drawdown is
A drawdown is a peak-to-trough decline during a specific period for an investment, trading account, or fund.
To put it simple, drawdown is how much does stock crash from peak to trough.
In addition to that, drawdown is recorded when peak's price has recovered later at some point.
To calculate drawdown, I break up into 2 points
find peak(which price is greater than 2 adjacent days' prices)
and trough (which price is lower than 2 adjacent days' prices)
When the peak's price has recovered, that peak, trough becomes a drawdown
Here is an example of stock quotation:
data class Quote(val price: Int, val date: String)
...
//example of quote
Quote(price:1, date:"20080102"),
Quote(price:2, date:"20080103"),
Quote(price:3, date:"20080104"),
Quote(price:1, date:"20080107"),
Quote(price:2, date:"20080108"),
Quote(price:3, date:"20080109"),
Quote(price:2, date:"20080110"),
Quote(price:4, date:"20080111"),
Quote(price:5, date:"20080114"),
Quote(price:6, date:"20080115"),
Quote(price:7, date:"20080116"),
Quote(price:8, date:"20080117"),
Quote(price:9, date:"20080118"),
Quote(price:7, date:"20080122"),
Quote(price:6, date:"20080123"),
Quote(price:8, date:"20080124"),
Quote(price:11,date:"20080125"),
list of drawdowns by date:
(peak: "20080104", trough:"20080107", daysTakenToRecover: 3),
(peak: "20080109", trough:"20080110", daysTakenToRecover: 2),
(peak: "20080118", trough:"20080123", daysTakenToRecover: 4),
Here is what is wrote for a test case:
class Drawdown {
var peak: Quote? = null
var trough: Quote? = null
var recovered: Quote? = null
var percentage: Double? = null
var daysToRecover: String? = null
}
data class Quote(
val price: Double,
val date: String
)
class Test {
private fun findDrawdowns(): List<Drawdown> {
val list = mutableListOf<Drawdown>()
var peak: Quote? = null
var trough: Quote? = null
var recovered: Quote? = null
for (quotation in quotations) {
val currentIdx = quotations.indexOf(quotation)
if (currentIdx in 1 until quotations.size - 1) {
val prevClosing = quotations[currentIdx - 1].price
val nextClosing = quotations[currentIdx + 1].price
val closing = quotation.price
recovered = when {
peak == null -> null
closing >= peak.price -> {
if (peak.date != quotation.date) {
//can possibly be new peak
Quote(closing, quotation.date)
} else null
}
else -> null
}
peak = if (closing > prevClosing && closing > nextClosing) {
if ((peak == null || peak.price < closing) && recovered == null) {
Quote(closing, quotation.date)
} else peak
} else peak
trough = if (closing < prevClosing && closing < nextClosing) {
if (trough == null || trough.price > closing) {
Quote(closing, quotation.date)
} else trough
} else trough
if (recovered != null) {
val drawdown = Drawdown()
val percentage = (peak!!.price - trough!!.price) / peak.price
drawdown.peak = peak
drawdown.trough = trough
drawdown.recovered = recovered
drawdown.percentage = percentage
drawdown.daysToRecover =
ChronoUnit.DAYS.between(
LocalDate.of(
peak.date.substring(0, 4).toInt(),
peak.date.substring(4, 6).toInt(),
peak.date.substring(6, 8).toInt()
),
LocalDate.of(
recovered.date.substring(0, 4).toInt(),
recovered.date.substring(4, 6).toInt(),
recovered.date.substring(6, 8).toInt()
).plusDays(1)
).toString()
list += drawdown
peak = if (closing > prevClosing && closing > nextClosing) {
Quote(recovered.price, recovered.date)
} else {
null
}
trough = null
recovered = null
}
}
}
val drawdown = Drawdown()
val percentage = (peak!!.price - trough!!.price) / peak.price
drawdown.peak = peak
drawdown.trough = trough
drawdown.recovered = recovered
drawdown.percentage = percentage
list += drawdown
return list
}
For those who want to read my code in github, here is a gist:
Find Drawdown in Kotlin, Click Me!!!
I ran some test cases and it shows no error.
So far, I believe this takes an O(n), but I want to make it more efficient.
How can I improve it? Any comments, thoughts are all welcomed!
Thank you and happy early new year.
There are two points
unfortunately the current complexity is the O(N^2)
for (quotation in quotations) {
val currentIdx = quotations.indexOf(quotation)
....
You have a loop through all the quotations, in which for each quotation you find its index. Finding the index is O(N) - look at indexOf docs. So total complexity will be O(N^2)
But you can easy fix it to O(N). Just replace foreach loop + indexOf with forEachIndexed, for example:
quotations.forEachIndexed { index, quote ->
// TODO
}
I think it's not possible to make it faster than O(N), because you need to check each quotation.

Using hour as a condition for intraday scripting?

I'd like to make a very basic strategy for intraday momentum.
However, I'm stuck wondering: is it possible to use hour as a trading condition?
For instance:
strategy("Strat - Intraday Momentum", overlay=true)
market_open = hour == 9
market_open_hour = hour == 10
market_close = hour == 15
if (market_open)
strategy.entry("Open", strategy.long)
if (market_open_hour)
strategy.entry("Open +1 Hour", strategy.long)
strategy.close_all(when= hour == market_close)
Seems simple enough but so far haven't been able to make it work.
Was playing off this idea:
// Simple Example Code
// Designed to play around with Tradingview's close, close_all and exit functions
strategy("Close Example", overlay=true, pyramiding=2)
monCondition = dayofweek == dayofweek.monday
wedCondition = dayofweek == dayofweek.wednesday
if (monCondition)
strategy.entry("Monday", strategy.long)
if (wedCondition)
strategy.entry("Wednesday", strategy.long)
strategy.close_all(when=dayofweek == dayofweek.friday)
Source: https://backtest-rookies.com/2019/03/01/tradingview-strategy-close-strategy-close_all-vs-strategy-exit/
It's possible for sure, but your code's robustness should be improved. Would be preferable to build conditions on transitions. Example 2 is from the usrman:
//#version=4
study("Time begin", "", true)
// #1
timeOpen1 = hour == 9
timeOpenOk1 = not timeOpen1[1] and timeOpen1
plotchar(timeOpenOk1, "timeOpenOk1", "", location.abovebar, text = "▲")
plotchar(timeOpen1, "timeOpen1", "", location.belowbar, text = "•")
// #2
sessSpec2 = input("0900-0959", type=input.session) + ":1234567"
is_newbar(res, sess) =>
t = time(res, sess)
na(t[1]) and not na(t) or t[1] < t
timeOpenOk2 = timeframe.isintraday and is_newbar("1440", sessSpec2)
plotchar(timeOpenOk2, "timeOpenOk2", "", location.abovebar, color.orange, text = "▲\n‎")

Editing the get_string function in Game Maker Studio 2

Everything works yet when I get prompted up to enter my name it looks like an error. Is there anyway I can edit it?
I am new to GameMaker, this is just my personal work for fun.
I have been looking online for a solution but it does not seem to be anywhere, I not sure if it's possible.
The following is the code that I am referring to.
if (currentHealth <= 0) {
name = get_string("Please enter your name: ","Anonymus");
highscore_add(name, global.points);
room_goto(GAMEOVER);
}
Maybe try "get_string_async()"
get_string should only be used for debugging. if you use get_string_async() your code will look like this
Create Event:
async = -1
input = 0
Step Event:
if (currentHealth <= 0 && input == 0) {
name = get_string_async("Please enter your name: ","Anonymus");
input = 1
}
Async_Dialogue Event:
var i_d = ds_map_find_value(async_load, "id");
if i_d == async
{
if ds_map_find_value(async_load, "status")
{
name = ds_map_find_value(async_load, "result");
highscore_add(name, global.points);
room_goto(GAMEOVER);
}
This works fine for me
If you want an "input field" (term to look for), you can use keyboard_string. For example,
Create:
keyboard_string = "";
Step:
if (keyboard_check_pressed(vk_enter)) {
input = keyboard_string;
// ... do something with `input`
}
Draw:
draw_text(x, y, keyboard_string);
Or a slightly less basic example that I made in 2013.

AS3: Sort Two Fields

PLEASE NEED HELP
This is what I'm doing:
var my_array_W:Array = new Array();
my_array_W.push({cor:Acorrect, tem:AnewTime, tab: "TB_A", nom:Aoseasnnombre});
my_array_W.push({cor:Bcorrect, tem:BnewTime, tab: "TB_B", nom:Boseasnnombre});
my_array_W.push({cor:Ccorrect, tem:CnewTime, tab: "TB_C", nom:Coseasnnombre});
my_array_W.push({cor:Dcorrect, tem:DnewTime, tab: "TB_D", nom:Doseasnnombre});
my_array_W.push({cor:Ecorrect, tem:EnewTime, tab: "TB_E", nom:Eoseasnnombre});
my_array_W.push({cor:Fcorrect, tem:FnewTime, tab: "TB_F", nom:Foseasnnombre});
This Output:
[tab] | [cor] | [tem]
TB_A 3 8.6877651541
TB_B 4 12.9287651344
TB_C 1 6199.334999999999923
TB_D 4 33.6526718521
TB_E 4 31.90468496844
TB_F 1 6.334999999923
So then I sort:
my_array_W.sortOn("tem", Array.NUMERIC);
my_array_W.sortOn("cor", Array.NUMERIC | Array.DESCENDING);
And Geting this T_T :
[tab] | [cor] | [tem]
TB_E 4 31.90468496844
TB_D 4 33.6526718521
TB_B 4 12.9287651344
TB_A 3 8.6877651541
TB_F 1 31.90468496844
TB_C 1 6199.334999999999923
I just wanna sort a Winner Table by Time(the less) and Correct(the high)
So the Winner is the One who make more correct answers in less time.
I really try so hard to get a sort like this:
[tab] | [cor] | [tem]
TB_B 4 12.9287651344
TB_E 4 31.90468496844
TB_D 4 33.6526718521
TB_A 3 8.6877651541
TB_F 1 6.334999999923
TB_C 1 6199.334999999999923
But couldn't achieve it
Your mistake is that you sort it 2 times. The second time does not additionally sort the sorted, it just sorts the whole Array anew. What you need is to use the Array.sort(...) method with a compareFunction argument:
my_array_W.sort(sortItems);
// Should return -1 if A < B, 0 if A == B, or 1 if A > B.
function sortItems(A:Object, B:Object):Number
{
// First, the main criteria.
if (A.cor > B.cor) return -1;
if (A.cor < B.cor) return 1;
// If A.cor == B.cor, then secondary criteria.
if (A.tem < B.tem) return -1;
if (A.tem > B.tem) return 1;
// Items seem to be equal.
return 0;
}
#Organis was so close.
But Finally I do the trick :D
With this line
my_array_W.sortOn(['cor', 'tem'],[ Array.NUMERIC | Array.DESCENDING, Array.NUMERIC ]);
I get the result I was looking for
Thanks
In your case you have to write a costume sorter function. to do that check my example:
Your first data:
var arr:Array = [];
arr.push({cor:4,tem:13});
arr.push({cor:3,tem:12});
arr.push({cor:2,tem:1});
arr.push({cor:3,tem:16});
arr.push({cor:1,tem:11});
The sorting function and sort result for sample one based on tem:
arr.sort(scrollSorter);
function temSorter(a,b):int
{
if(a.tem<b.tem)
return 1 ;//To pass a forward
else(a.tem>b.tem)
return -1;//To pass a backward
return 0;//a and b are same.
}
And the result is:
The result is this:
[
{
"cor": 3,
"tem": 16
},
{
"cor": 4,
"tem": 13
},
{
"cor": 3,
"tem": 12
},
{
"cor": 1,
"tem": 11
},
{
"cor": 2,
"tem": 1
}
]
Now the sample based on something close you need:
arr.sort(scrollSorter);
function userScoreCalculator(a):Number
{
return a.cor/a.tem;
}
function winnerSorter(a,b):int
{
var aScore:Number = userScoreCalculator(a);
var bScore:Number = userScoreCalculator(b);
if(aScore<bScore)
return 1 ;
else(aScore>bScore)
return -1
return 0
}
And the result is:
[
{
"cor": 2,
"tem": 1
},
{
"cor": 4,
"tem": 13
},
{
"cor": 3,
"tem": 12
},
{
"cor": 3,
"tem": 16
},
{
"cor": 1,
"tem": 11
}
]
Than means the person with score of 2 is winner because he made it in only 1 second. but other players are close to gather in tem parameter, so the next winner is the person with highest score. it comes from the userScoreCalculator() output. the higher output of that function is the winner.
Now take your time and change the userScoreCalculator() function to show the winner.
https://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fa4.html

Resources