LUNAR

All Submissions Basics:

[ ] Have you followed the guidelines in our Contributing document?
[ ] Have you checked to ensure there aren't other open Pull Requests for the same update/change?
[ ] Have you checked all Issues to tie the PR to a specific one?

All Submissions Cores:

[ ] Have you added an explanation of what your changes do and why you'd like us to include them?
[ ] Have you written new tests for your core changes, as applicable?
[ ] Have you successfully ran tests with your changes locally?
[ ] Does your submission pass tests, including CircleCI, Travis CI, and AppVeyor?
[ ] Does your submission have appropriate code coverage? The cutoff threshold is 95% by Coversall.

New Model Submissions:

[ ] Have you created a .py in ~/pyod/models/?
[ ] Have you created a _example.py in ~/examples/?
[ ] Have you created a test_.py in ~/pyod/test/?
[ ] Have you lint your code locally prior to submission?

Dear agoodge,
LUNAR sounds like an interesting method! Maybe you can also implement LUNAR using Tensforflow?

Dear @agoodge,
I tried to use LUNAR, and I found out that you miss a part in your implementation:
https://github.com/agoodge/pyod/blob/20716cb2c3f60e8d984394fa394f09d2772b559f/pyod/models/lunar.py#L264
In this line (above) you should add the following line of code:
self.decision_scores_ = self.decision_function(X)
self._process_decision_scores()

Then I can run LUNAR completely, and it looks good!

Hi @mbongaerts!
Thanks for your interest in LUNAR!
Please could you explain why those two lines are necessary there? I'm not familiar enough.
Thanks a lot!
Adam

Hi @mbongaerts!
Thanks for your interest in LUNAR!
Please could you explain why those two lines are necessary there? I'm not familiar enough.
Thanks a lot! Adam

That is because the BaseDetector class (base.py) wants you to assign self.decision_scores_ i.e. the scores of the train set. If you look at this class, these scores are then used for some other metrics such as threshold_ and labels_. In order to calculate the latter we need to class the BaseDetector method _process_decision_scores. Without this addition, you model will not pass the standard test pipeline.

There are actually more points to work on:

Maybe you want to include no pre-processing and also the StandardScaler() as options? Now, you automatically use the MinMaxScaler() line

Look for example at this model AutoEncoder

I think that splitting train- and test set in the fit() function is generally not wanted, since as a user I assume that when I fit my model the whole train set is used. But I understand from the code that you select the best model based on the best val_score. At least, let the user decide the value for test_size.  line

You miss a check that makes sure the model is fitted before using decision_function() line

I made some changes, you (@agoodge) can look if you like them.
# -*- coding: utf-8 -*-
"""LUNAR
"""
# Author: Adam Goodge<EMAIL_ADDRESS>#

import os
from copy import deepcopy
from sklearn.metrics import roc_auc_score
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.neighbors import NearestNeighbors
from sklearn.utils import check_array
from sklearn.utils.validation import check_is_fitted

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

from .base import BaseDetector

# negative samples for training
def generate_negative_samples(x, sample_type, proportion, epsilon):

    n_samples = int(proportion*(len(x)))
    n_dim = x.shape[-1]

    # uniform samples
    rand_unif = np.random.rand(n_samples,n_dim).astype('float32')
    # subspace perturbation samples
    x_temp = x[np.random.choice(np.arange(len(x)),size = n_samples)]
    randmat = np.random.rand(n_samples,n_dim) < 0.3
    rand_sub = x_temp + randmat*(epsilon*np.random.randn(n_samples,n_dim)).astype('float32')

    if sample_type == 'UNIFORM':
        neg_x = rand_unif
    if sample_type == 'SUBSPACE':
        neg_x = rand_sub
    if sample_type == 'MIXED':
        # randomly sample from uniform and gaussian negative samples
        neg_x = np.concatenate((rand_unif, rand_sub),0)
        neg_x = neg_x[np.random.choice(np.arange(len(neg_x)), size = n_samples)]

    neg_y = np.ones(len(neg_x))

    return neg_x.astype('float32'), neg_y.astype('float32')

class SCORE_MODEL(torch.nn.Module):
        def __init__(self,k):
            super(SCORE_MODEL, self).__init__()
            self.hidden_size = 256
            self.network = nn.Sequential(
                nn.Linear(k,self.hidden_size),
                nn.Tanh(),
                nn.Linear(self.hidden_size,self.hidden_size),
                nn.Tanh(),
                nn.Linear(self.hidden_size,self.hidden_size),
                nn.Tanh(),
                nn.Linear(self.hidden_size,1),
                nn.Sigmoid()
                )

        def forward(self,x):
            out = self.network(x)
            out = torch.squeeze(out,1)
            return out

class WEIGHT_MODEL(torch.nn.Module):
        def __init__(self,k):
            super(WEIGHT_MODEL, self).__init__()
            self.hidden_size = 256
            self.network =  nn.Sequential(
                            nn.Linear(k,self.hidden_size),
                            nn.ReLU(),
                            nn.Linear(self.hidden_size,self.hidden_size),
                            nn.ReLU(),
                            nn.Linear(self.hidden_size,self.hidden_size),
                            nn.ReLU(),
                            nn.LayerNorm(self.hidden_size),
                            nn.Linear(self.hidden_size,k),
                            )
            self.final_norm = nn.BatchNorm1d(1)

        def forward(self,x):
            alpha = self.network(x)
            # get weights > 0 and sum to 1.0
            alpha = F.softmax(alpha, dim = 1)
            # multiply weights by each distance in input vector
            out = torch.sum(alpha * x, dim=1, keepdim=True)
            # batch norm
            out = self.final_norm(out)
            out = torch.squeeze(out,1)
            return out

class LUNAR(BaseDetector):
    """
    LUNAR class for outlier detection. See https://www.aaai.org/AAAI22Papers/AAAI-51.GoodgeA.pdf for details.

    For an observation, its ordered list of distances to its k nearest neighbours is input to a neural network,
    with one of the following outputs:

        1) SCORE_MODEL: network directly outputs the anomaly score.

        2) WEIGHT_MODEL: network outputs a set of weights for the k distances, the anomaly score is then the
                         sum of weighted distances.

    Parameters
    ----------

    model_type: str in ['WEIGHT', 'SCORE'], optional (default = 'WEIGHT')
        Whether to use WEIGHT_MODEL or SCORE_MODEL for anomaly scoring.

    n_neighbors: int, optional (default = 5)
        Number of neighbors to use by default for k neighbors queries.

    negative_sampling: str in ['UNIFORM', 'SUBSPACE', MIXED'], optional (default = 'MIXED)
        Type of negative samples to use between:
            'UNIFORM': uniformly distributed samples
            'SUBSPACE': subspace perturbation (additive random noise in a subset of features)
            'MIXED': a combination of both types of samples

    epsilon: float, optional (default = 0.1)
        Hyper-parameter for the generation of negative samples.
        A smaller epsilon results in negative samples more similar to normal samples.

    proportion: float, optional (default = 1.0)
        Hyper-parameter for the proprotion of negative samples to use relative to the
        number of normal training samples.

    n_epochs: int, optional (default = 200)
        Number of epochs to train neural network.

    lr: float, optional (default = 0.001)
        Learning rate.

    wd: float, optional (default = 0.1)
        Weight decay.

    verbose: int in [0,1], optional (default = 0):
        To view or hide training progress

    Attributes
    ----------

    """
    def __init__(self, model_type = "WEIGHT", n_neighbours = 5, negative_sampling = "MIXED", test_size = 0.1,
                 scaler = None, epsilon = 0.1, proportion = 1.0, n_epochs = 200, lr = 0.001, wd = 0.1, verbose = 0):
        super(LUNAR, self).__init__()

        self.model_type = model_type
        self.n_neighbours = n_neighbours
        self.negative_sampling = negative_sampling
        self.epsilon = epsilon
        self.proportion = proportion
        self.n_epochs = n_epochs
        self.scaler = scaler
        self.lr = lr
        self.wd = wd
        self.test_size = test_size
        self.verbose = verbose
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

        if model_type == "SCORE":
            self.network = SCORE_MODEL(n_neighbours).to(self.device)
        elif model_type == "WEIGHT":
            self.network = WEIGHT_MODEL(n_neighbours).to(self.device)

    def fit(self, X, y=None):
        """Fit detector. y is assumed to be 0 for all training samples.

        Parameters
        ----------
        X : numpy array of shape (n_samples, n_features)
            The input samples.

        y : Ignored
            Overwritten with 0 for all training samples (assumed to be normal).

        Returns
        -------
        self : object
            Fitted estimator.
        """

        X = check_array(X)
        X = X.astype('float32')
        y = np.zeros(len(X))

        #split training and validation sets
        train_x, val_x, train_y, val_y = train_test_split(X, y, test_size= self.test_size )

        #fit data scaler to the training set if scaler has been passed
        if( self.scaler == None):
            pass
        else:
            self.scaler.fit(train_x)

        # generate negative samples for training and validation set seperately
        neg_train_x, neg_train_y = generate_negative_samples(train_x,self.negative_sampling,self.proportion,self.epsilon)
        neg_val_x, neg_val_y = generate_negative_samples(val_x,self.negative_sampling,self.proportion,self.epsilon)
        # concatenate data
        x = np.vstack((train_x,neg_train_x,val_x,neg_val_x))
        y = np.hstack((train_y,neg_train_y,val_y,neg_val_y))

        # scale data if scaler has been passed
        if( self.scaler == None):
            pass
        else:
            x = self.scaler.transform(x)

        # mask for the training set
        train_mask = np.hstack((np.ones(len(train_x)),np.ones(len(neg_train_x)),
                                np.zeros(len(val_x)),np.zeros(len(neg_val_x))))
        # mask for the normal training points (used for nearest neighbour search)
        neighbor_mask = np.hstack((np.ones(len(train_x)), np.zeros(len(neg_train_x)),
                                np.zeros(len(val_y)), np.zeros(len(neg_val_x))))
        # nearest neighbour search
        self.neigh = NearestNeighbors(n_neighbors= self.n_neighbours+1)
        self.neigh.fit(x[neighbor_mask==1])
        dist_train, _ = self.neigh.kneighbors(x[neighbor_mask==1], n_neighbors = self.n_neighbours+1)
        # remove self loops in normal training points
        dist_train = dist_train[:,1:]
        dist, _ = self.neigh.kneighbors(x[neighbor_mask==0], n_neighbors = self.n_neighbours)
        #concatenate distances of different samples
        dist = np.vstack((dist_train, dist))
        dist = torch.tensor(dist,dtype=torch.float32).to(self.device)
        y = torch.tensor(y,dtype=torch.float32).to(self.device)
        #loss function
        criterion = nn.MSELoss(reduction = 'none')
        # optimizer
        optimizer = optim.Adam(self.network.parameters(), lr = self.lr, weight_decay = self.wd)
        # for early stopping
        best_val_score = 0
        # model training
        for epoch in range(self.n_epochs):

            # see performance of model before epoch
            with torch.no_grad():

                self.network.eval()
                out = self.network(dist)
                out = out.cpu()
                loss = criterion(out,y.cpu())
                train_score = roc_auc_score(y[train_mask==1].cpu(), out[train_mask==1])
                val_score = roc_auc_score(y[train_mask == 0].cpu(), out[train_mask == 0])

                # save best model
                if val_score >= best_val_score:
                    best_dict = {'epoch': epoch,
                                'model_state_dict': deepcopy(self.network.state_dict()),
                                'optimizer_state_dict': deepcopy(optimizer.state_dict()),
                                'train_score': train_score,
                                'val_score': val_score,
                                }

                    # reset current best score
                    best_val_score = val_score

                if self.verbose == 1:
                    print(f"Epoch {epoch} \t Train Score {np.round(train_score,6)} \t Val Score {np.round(val_score,6)}")

            #training loop
            self.network.train()
            optimizer.zero_grad()
            out = self.network(dist)
            loss = criterion(out[train_mask == 1],y[train_mask == 1]).sum()
            loss.backward()
            optimizer.step()

        #print best model after training
        if self.verbose == 1:
            print(f"Finished training...\nBest Model: Epoch {best_dict['epoch']} \t Train Score {best_dict['train_score']} \t Val Score {best_dict['val_score']}")
        # load best model after training
        self.network.load_state_dict(best_dict['model_state_dict'])

        # Determine outlier scores for train set
        # scale data if scaler has been passed
        if( self.scaler == None):
            X_norm  = X
        else:
            X_norm = self.scaler.transform(X)

        # nearest neighbour search
        dist, _ = self.neigh.kneighbors(X_norm,self.n_neighbours)
        dist = torch.tensor(dist,dtype=torch.float32).to(self.device)
        #forward pass
        with torch.no_grad():
            self.network.eval()
            anomaly_scores = self.network(dist)

        self.decision_scores_ = anomaly_scores.cpu().detach().numpy()
        self._process_decision_scores()

        return self

    def decision_function(self, X):
        """Predict raw anomaly score of X using the fitted detector.

        For consistency, outliers are assigned with larger anomaly scores.

        Parameters
        ----------
        X : numpy array of shape (n_samples, n_features)
            The training input samples.

        Returns
        -------
        anomaly_scores : numpy array of shape (n_samples,)
            The anomaly score of the input samples.
        """

        check_is_fitted(self, ['decision_scores_'])
        X = check_array(X)
        X = X.astype('float32')

        # scale data
        if( self.scaler == None):
            pass
        else:
            X = self.scaler.transform(X)

        # nearest neighbour search
        dist, _ = self.neigh.kneighbors(X,self.n_neighbours)
        dist = torch.tensor(dist,dtype=torch.float32).to(self.device)
        #forward pass
        with torch.no_grad():
            self.network.eval()
            anomaly_scores = self.network(dist)
        return anomaly_scores.cpu().detach().numpy()

Dear @agoodge, I made some changes to your code and everything should work now properly. Please checkout my pull request: #421

Thanks for your useful input @mbongaerts! I've implemented the changes you suggested in this PR now.

Dear @agoodge, I made some changes to your code and everything should work now properly. Please checkout my pull request: #421

Thanks for your useful input @mbongaerts! I've implemented the changes you suggested in this PR now.

Looks good! Maybe, you also want to give a warning/error to the user if they don't use the MinMaxScaler and using MIXED or UNIFORM as negative samples?
Something like:
if( (scaler == None) and (negative_sampling in [ 'UNIFORM' , 'MIXED' ]) ):
    raise AssertionError("scaler=None cannot be used in combination with negative_sampling is 'UNIFORM' or 'MIXED' ")

Dear @agoodge, did you consider this option? I am happy to know what you think.

Hi @mbongaerts
I'm trying to fix the appveyor issue currently. After that works fine then I'll look more at what can be done to improve the code :)

Dear @agoodge, I made some changes to your code and everything should work now properly. Please checkout my pull request: #421

Thanks for your useful input @mbongaerts! I've implemented the changes you suggested in this PR now.

Looks good! Maybe, you also want to give a warning/error to the user if they don't use the MinMaxScaler and using MIXED or UNIFORM as negative samples?
Something like:
if( (scaler == None) and (negative_sampling in [ 'UNIFORM' , 'MIXED' ]) ):
    raise AssertionError("scaler=None cannot be used in combination with negative_sampling is 'UNIFORM' or 'MIXED' ")

Dear @agoodge, did you consider this option? I am happy to know what you think.

Hi @mbongaerts
I'm trying to fix the appveyor issue currently. After that works fine then I'll look more at what can be done to improve the code :)

Well, let me know because I have the same problem with two pull requests. I think its the exact same error:
https://ci.appveyor.com/project/yzhao062/pyod/builds/44031338/job/o5hsb6ks9qid48cw
https://ci.appveyor.com/project/yzhao062/pyod/builds/44007288/job/1p1dxwv2ogk7q8wx
It looks like an error in check_array() of sklearn.

Hey folks, I have addressed the test error caused by the behavior change of the data generator. It is all cool now.
If this will not have any further changes, I will add LUNAR and R-graph in v1.0.4, which is likely out in a month or so. We usually only add 2 algorithms per release so v1.0.3 is already packed now :)
Your contribution is also acknowledged here: https://pyod.readthedocs.io/en/latest/about.html

Hey folks, I have addressed the test error caused by the behavior change of the data generator. It is all cool now. If this will not have any further changes, I will add LUNAR and R-graph in v1.0.4, which is likely out in a month or so. We usually only add 2 algorithms per release so v1.0.3 is already packed now :)
Your contribution is also acknowledged here: https://pyod.readthedocs.io/en/latest/about.html

@yzhao062 That's good to know - thanks! Looking forward to it :)

Hey folks, I have addressed the test error caused by the behavior change of the data generator. It is all cool now. If this will not have any further changes, I will add LUNAR and R-graph in v1.0.4, which is likely out in a month or so. We usually only add 2 algorithms per release so v1.0.3 is already packed now :)
Your contribution is also acknowledged here: https://pyod.readthedocs.io/en/latest/about.html

Great! Thanks!


Upload packages automatically

Upload packages to PyPI and Conda-Forge
Automatically in CI when new tag on main branch

Will be solved by #66


Split pages for long documents

User research on the Verify Tech Guide shows that users get to the end of a procedure and carry on scrolling down whereas it would be more appropriate to stop and go to another place in the document.
The process of onboarding with Verify isn't linear. You have to do the same thing in different environments so there is a degree of flitting backwards and forwards in the doc. Users miss this because it's one long page. It would be good to chunk information.

This is now tracked in https://github.com/alphagov/tech-docs-template/issues/128.


Revert "workaround bug in ParallelEnumerable"

Reverts fsprojects/FSharp.Collections.ParallelSeq#6

@sergey-tihon @forki On reviewing it more, that Any doesn't do what I thought it did.  From the source ref: "Determines whether a parallel sequence contains any elements."  I guess this one will have to stay open until the underlying library is fixed.


API for mods integration

I think that API will be over-kill for that small project.
Also in latest release I added support for non-vanilla dimensions


Improve question creation errors handling

Current behavior
Currently, frontend does not notify use about any BE errors happening during question/post creations.
Expected/desired behavior

Add errors handling for unexpected events (e.g critical BE exception)
Add buttons loading states (disabled)
Add console.error logging

Doesn't seem blocking for launch, am I missing something?

Who should QA this? I'm assuming @hlbmtc ?

Ready for testing on dev and prod


Yarn couldn't find a configuration settings named "cache-folder"

Is there an existing issue for this?

[X] I have searched the existing issues

Run a Diagnostic and Paste Link Here
No response
Current Behavior
The Web Container does not start. This is due to the error message thrown by Yarn.
+ yarn config set cache-folder /mnt/ddev-global-cache/yarn/newsportal-web
Usage Error: Couldn't find a configuration settings named "cache-folder"

In the project itself Yarn v3.2.2 is installed. There the configuration name is "cacheFolder" (see https://yarnpkg.com/configuration/yarnrc#cacheFolder)
Expected Behavior
Checking the Yarn version and setting the cache accordingly.
Steps To Reproduce
No response
Anything else?
No response

Thanks so much fo the clear report.
I got to study this problem yesterday in a workshop I was teaching, and the problem is indeed an incompatibility with yarn3 being site-installed, since it has this breaking change. The ddev-webserver has yarn 1 in it, and the command is correct for yarn1, but fails with yarn 3, and when yarn 3 is site-installed, yarn1 runs yarn3 and then gets this result.
I confess that I didn't even know there was a yarn 3, or that it would be site-installed and have a dramatic breaking change like this.
From studying it yesterday I understand how to mitigate the problem and will do a PR shortly to do that and we'll have a new release in a couple of days. But I would prefer to understand how to reproduce this in a simple project first. Would it be possible for you to make a trivail project that demonstrates it and push it up to a repo?

I guess it's quite a mess and quite a surprise, https://yarnpkg.com/getting-started/migration#why-should-you-migrate
Amazing that they wouldn't move the default installation technique along, but whatever.

I'm able to recreate with the process in https://yarnpkg.com/getting-started/migration#why-should-you-migrate


Select multiple boxes and apply a label

select multiple boxes and apply a label to them or delete them as a group. possibly while holding a key to add to the selection.

Partially addressed in dev-branch: you can select multiple boxes with shift-key pressed for basic manipulation like deleting or moving from the keyboard.
Applying a label for multiple tags is not implemented yet.

a click and drag option to select multiple boxes would be useful since selecting >10 boxes by clicking on each could be very tedious.


[Experiment] Improve enumeration performance by delaying loading of extended item properties until after enumeration has completed

Resolved / Related Issues
Items resolved / related issues by this PR.

Closes #issue...
Related #issue...

Details of Changes
Add details of changes here.

Delay loading of extended item properties until after enumeration has completed

Validation
How did you test these changes?

[x] Built and ran the app
[ ] Tested the changes for accessibility

Screenshots (optional)
Add screenshots here.
This seems to decrease the enumeration speed, but I'm not certain, would appreciate input on this.

@winston-de @yaichenbaum In my testing with this PR on my machine, I loaded System32 on both versions. Can confirm a 39% improvement in that initial load speed time calculated by the Stopwatch in ItemViewModel:
C:\Windows\System32:
713 ms - Winston's changes
1170 ms - Main branch

Perceived performance could be even better on different configurations, but it is difficult to quantify that.

@duke7553 it looks like this is still a draft, I'm curious what else Winston has in store for this PR...

@duke7553 it looks like this is still a draft, I'm curious what else Winston has in store for this PR...

Nothing more, sorry. I had it as a draft to get input as to whether it actually worked.


Meteor Autocomplete Type Error

Hi
I am using  aldeed:autoform,mizzao:autocomplete and mpowaga:autoform-autocomplete.
I am also using Ionic due to which I am @Autoform:4.2.2 version.
I get following error when I try to use Autocomplete.
TypeError: Cannot read property 'limit' of undefined
    at new AutoComplete (mizzao_autocomplete.js:171)
    at autocompleteHelpers.autocompleteContainer [as _render] (mizzao_autocomplete.js:570)
    at doRender (view.js:351)

Can u tell me what is the issue here. Everything else in schema etc are very straight forward exactly as your example
Registers2.attachSchema(new SimpleSchema({
  /* ... */
  title: {
    type: String,
    autoform: {
      afFieldInput: {
        type: 'autocomplete-input',
        placeholder: 'Title',
        settings : { position: "top",
                    limit: 5,
                    rules: [
                      {
                        token: '',
                        collection: Registers,
                        field: "config.name",
                        template: Meteor.isClient &&  Template.contactlisting
                      }]}}}},
  content: {
    type: String,
    autoform: {
      afFieldInput: {
        type: 'autocomplete-textarea',
        rows: 4
      }   }  }}));

I've never used mpowaga:autoform-autocomplete so I can't help, although I would like this to support autoform at some point (#9, #91). Just haven't found the time to do that yet.


Add signin + copy to anon package view

Implements first mock from https://github.com/gratipay/gratipay.com/issues/4297#issuecomment-273854209.

Ready for review, @JessaWitzel @mattbk @nobodxbodon.

Note that the base is #4305 and not master, so we should be good to merge even though the final state is incomplete.


add Moment.prototype.creationData

This function returns an object containing the input format, input value, locale, and whether the moment was created in UTC.
Resolves #2443

How is that different from #2565 ?

The only difference is that it includes a test for an invalid date, which was my original use-case. Otherwise, a dup

Close because #2565 was merged.


DRY up show lag handling

@jipengzhu -- I'd like to DRY up the code a little. Look good to you?

@otoolep The independent method makes the logic more clearer , will it be better?

@jipengzhu -- I know what you're saying, but I feel there is too much repeated code with the previous way.

ok  👌

Thanks @jipengzhu

@jipengzhu -- I will say that the code here is pretty basic, it was written quite a while ago. It could do with a serious refactor, if you felt like it. I'm sure you could make it nicer and still retain the current default behavior.

@otoolep
ok, thanks.
if i have enough time ,  i will do it.


Feature request timeline

Select one ...  (check one with "x")
[ ] bug
[x] feature request
[ ] enhancement

Expected behavior

To have a nice timeline feature, that can be inserted in a card, for example. Something like google chart has. Or like what we can see in PrimeNg Ultima template http://www.primefaces.org/ultima-ng/
Actual behavior

Reproduction of behavior

Environment details

Angular version: 2.0.X

Clarity version:

OS and version:

Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]


feature request - dynamicPriceFormula

I think it would make sense to have an optional dynamic price formula. I'm not sure what it should use, though - possibly just Lua with only some math functions? I think that would make implementing parsing for it without Lua not too complex, and simple with Lua.

[!NOTE]
My idea was clear in my head, but become way too over engineered. This is probably not a great solution.

I suggest we add an optional dynamicPriceFormula on items. If it is not used it should be nil. If it is used, dynamicPrice must be true, but dynamicPriceFormula isn't required if you have dynamicPrice. dynamicPriceForumula's string contains tokens. Spaces are not permitted. There are three types of tokens. PEMDAS must be respected.
Operators must have a value before or after. Operator tokens:

+
-
/
*
^
(
)

Function tokens must have values inside of the parentheses, separated by , . Function tokens:

abs
acos
asin
atan
ceil
floor
round
tan
sqrt
min
max

Static tokens are static. Static tokens:

pi

There are placeholders which should be replaced by the consumer:

{{AMOUNT}} The amount of items to get the price for.

Examples:

floor(69^{{AMOUNT}})
{{AMOUNT}}*20+{{AMOUNT}}^2+2 - Every item costs 20 krist, an additional x ^ 2 volume tax, and a static 2 krist receipt printing tax

I'd say that using Lua syntax would make sense considering it could be executed in a limited environment. I'll see what I can do, PRs are ofc welcome

I am against this idea - I feel like, with the amount of shops using dynamic pricing, it might just be easier for ShopSync receivers to hardcode the formulas for specific shops. I believe SP uses an iterative formula for calculating item pricing, which wouldn't really fit into the proposed scheme anyways, and otherwise there's only the LP.
If we do want to include this anyways, I have a few ideas:

using S-expressions, e.g. {"floor", {"^", "69", "amount"}} so that receivers don't have to write parsers. I like this option the best because it's both fairly simple and language-agnostic (and it complies with Greenspun's tenth rule)
just using Lua expressions but with no function creation or string metatable allowed
some expansion of the two options above to support iterative formulas

S-expressions seem to make more sense, so we should probably use those. I don't like the idea of implementing iterative formulas, though, because they likely wouldn't be very fast and it sounds like a pain to make calculating them safe.


[FEATURE REQUEST] Reference between defined service resources

Which area is mainly impacted
Cloud Foundry setups
Requested Feature
While considering the usage of the btp setup automator in a project the following situation showed up. There is maybe a way to achieve this I'm missing but take this as a possible suggestion.
On the scenario I'm building I will instantiate a SAP launchapd service to host some site. I would want to also use the Cloud Transport Management service. I have created instances for both the Launchpad and the Cloud Transport Management in my use case. When creating the Cloud Transport Management service I generate a service key that will be required in a ctms_destination destination that needs to be setup.
I also create the destination in the use case but I would need to reference the service key credentials from the service key that gets generated when instantiating the Cloud Transport Management service. Is there a way to reference artifacts generated on another service on the description of another service in the use case? What I'd be thinking of would be that the use case references the service key parameters from an object that is generated in a previous step., in this case referencing the service key that gets generated in the Cloud Transport Management service in a destination that gets generated at a later stage in the same use case.
Use Case/Scenario
{
"aboutThisUseCase": {
"name": "Setup CF Environment Example",
"description": "This use case serves to show an example of need to reference service attributes from another service",
"author": "raiatdeloitte",
"testStatus": "to be tested",
"usageStatus": "IN DEVELOPMENT",
"relatedLinks": [
]
},
"services": [
{
"name": "SAPLaunchpad",
"plan": "standard",
"category": "APPLICATION"
},
{
"name": "transport",
"plan": "standard",
"category": "SERVICE",
"createServiceKeys": [
"transport-ServiceKey" // This line is the one generating a service key
]
},
{
"name": "destination",
"plan": "lite",
"category": "SERVICE",
"parameters": {
"cfspacename":"$cf_space",
"HTML5Runtime_enabled": "true",
"init_data": {
"subaccount": {
"existing_destinations_policy": "fail",
"destinations": [
{
"Name": "cmts_destination",
"Type": "HTTP",
"URL": "http://sap.com",
"tokenServiceURL": "/oauth/token",
"Authentication": "OAuth2ClientCredentials",
"ProxyType": "Internet",
"Description": "Cloud Transport Management destination",
"clientId": "transport-sk-user", // I'd like to be able to reference the result of the execution of the generation of transport-ServiceKey here
"clientSecret": "transport-sk-pass", // I'd like to be able to reference the result of the execution of the generation of transport-ServiceKey here
"tc.languages": "en-GB,es-ES"
}
]
}
}
}
}
]
}
Would you like to support us?

[ ] Yes, I would like to support you

Anything else?
Take this as a suggestion of a nice to have. Not saying it should be implemented right away or as proposed. Also, maybe it's already possible and I missed the point.

Hi @raiatdeloitte , have you considered using the executeAfterAccountSetup attribute in the usecase.json file and combining it with the collected data in the log file metadata_log.json?
That should bring you already a few steps further. But as long as you won't be able to contribute it will be difficult to address your feature request in a timely manner.
For now, I'll keep this request open. Thanks for your request!

No feedback since 15th of July, so I will close this issue. If the request is still relevant, please re-open the issue


Mic volume

m.setOnAmplitudeListener(new AmplitudeListener() {
  @Override
  public void onSample(double amplitude, double volume) {
    Log.e("TalkFragment","(:160)"+volume);
  }
});

Mic decibels cannot be obtained

Please provide a set of reproducible steps. Check the CONTRIBUTING.md for an example.

Closing due to inactivity.


Sirius doesn't properly report exceptions

For example, this exception:
1475│     int npk = comm_.size() / npb;
1476│     if (npk * npb != comm_.size()) {
1477│         std::stringstream s;
1478│         s << "Can't divide " << comm_.size() << " ranks into groups of size " << npb;
1479├───────> RTE_THROW(s);
1480│     }

in src/context/simulation_context.cpp causes Abort trap:
$ sirius.scf --test_against=output_ref.json --control.processing_unit=cpu --control.mpi_grid_dims=2:2 --control.std_evp_solver_name=scalapack --control.gen_evp_solver_name=scalapack
SIRIUS 7.4.3, git hash: https://api.github.com/repos/electronic-structure/SIRIUS/git/ref/tags/v7.4.3
Warning! Compiled in 'debug' mode with assert statements enabled!
Abort trap

The error message is lost.
Linux reports lost exceptions anyway, but other OSes do not - such reporting is a linux extension and is not covered by the C++ standard.
You need to have a proper try-catch block in your main function.

Implemented in 'develop'


Implement .fileFrom()?

https://uploadcare.com/documentation/javascript_api/

This is possible: uploadcare.file.fromUrl
https://github.com/RexMorgan/uploadcare-node/blob/7c7ca635fce85c4c94f6930f48bd8053fa454ac0/lib/main.js#L175


Add Umme Ammara to Contributors list

Please note that for legal reasons we require you to sign the
Contributor Agreement
before we can accept your pull requests.

Please don't waste other peoples time just to gain some score in Hacktoberfest. Come back when you found something usefull.


Added Pixabay Image/Video scraper

Description
I've added the pixaby image and video scraper. It directly saves the relevant images and videos into user's local storage.
Colab notebook of project: https://colab.research.google.com/drive/1E0FTrpZk58JKIMpKvilP7rt8WtkKe9ms?usp=sharing
Resolves: #561
Checklist

Before submitting this pull request, kindly verify that the ensuing checkpoints have been reached.

[x] Have you adhered to the repository's defined coding convention rules?
[x] Have you updated the 'documentation.md' file with the method/function documentation?
[x] Have you sent a message along with the result or response?
[x] Have you used the try-catch technique?
[x] Has the method/class been added to the documentation (md file)?

Screenshots

get_videos():

get_photos():

Uploading a screenshot illustrating the approach you developed for validation is required.

Additional Notes/Comments

Any additional remarks or suggestions concerning this pull request are welcome.

I certify that I have carried out the relevant checks and provided the requisite screenshot for validation by submitting this pull request.
I appreciate your contribution.

@nikhil25803 please review this PR.

Hey @nikhil25803

I've made the API key private so that users would not be able to access it.
I've also made the helper functions private, restricting their access.

@nikhil25803 please see this PR


Ignore Non AR subclasses

I've been trying to get an isolated failing spec for this, but I don't quite fully understand the code and specs of this project yet.
If we have Foo and that inherits from top level class Bar then I'd rather not see any errors or warnings like:
Foo does not inherit from ActiveRecord::Base
Bar is missing a parent class.

BTW, happy to help contribute to the project if you can give pointers. We have a bit of time to look at improving our test suite, and one option is to look at using active_mocker to speed things up, if we can get it to work

This was mostly just for debugging and I made the assumption that the model_dir would only contain ActiveRecord models. I could add a flag to ignore such cases.
In my past projects I would put classes as you are mentioning in the lib directory.

That's not the case for us, and not an option really as the project is huge. Model doesn't necessarily mean the Active Record design pattern. It also doesn't necessarily mean ActiveRecord, the Rails gem.
You can have models that are not persisted. Or persistence related classes that are not necessarily domain concepts or 'models'.
I think it would make sense that the project defaults to just skipping over non AR subclasses. Would you agree? It would also solve the problem with concerns modules causing exceptions.

I think the bast way to deal with this is to only have these show up when in debug mode and they should not count as a failure. Since this is not a blocking issue and only a nice to have I'm going to prioritize less than the other issues you've have raised.

I've got a local fix for this, so will get a test for it and do a PR
tomorrow and see what you think.
On Thu, 28 Apr 2016 at 01:39, Dustin Zeisler<EMAIL_ADDRESS>wrote:

I think the bast way to deal with this is to only have these show up when
in debug mode and they should not count as a failure. Since this is not a
blocking issue and only a nice to have I'm going to prioritize less than
the other issues you've have raised.
—
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
https://github.com/zeisler/active_mocker/issues/44#issuecomment-215142167


patroni: assume etcd to be in same namespace by default

https://github.com/kubernetes/charts/pull/137 broke the patroni chart as it depended on the namespace being defined in values.yaml.
this fixes it by telling patroni to lookup etcd in its own namespace by default.

ok, i missed the fix was already here.
any opinions about defining the location of etcd this way?

Thanks @linki, and sorry for breaking it the first time!
I guess this change is essentially the same as the one in https://github.com/prydonius/charts/commit/398ccd253a619546b127946c3ab4ca79cecaeaef#diff-6143213a6ec610c932981400d62877a7R47, except that one is more explicit with the namespace. As far as I can tell, either way should not be too much of an issue since etcd will be deployed in the same namespace as patroni using Helm.
It's your call!

@k8s-bot ok to test

thinking about it again I like this PR more:

it get's the trucation logic right (long release names would truncate the service name)
it works in case cluster dns domain is different from "cluster.local"

@linki sgtm! Thanks :)