<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

'use strict';

KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $location, $templateCache, $interpolate, MessageService, TableService, CubeDescService, ModelService, loadingRequest, SweetAlert,$log,cubeConfig,CubeDescModel,ModelDescService,MetaModel,TableModel,ProjectService,ProjectModel,modelsManager) {
    //add or edit ?
    var absUrl = $location.absUrl();
    $scope.modelMode = absUrl.indexOf("/models/add")!=-1?'addNewModel':absUrl.indexOf("/models/edit")!=-1?'editExistModel':'default';

    if($scope.modelMode=="addNewModel"&&!ProjectModel.getSelectedProject()){
        SweetAlert.swal('Oops...', 'Please select your project first.', 'warning');
        $location.path("/models");
    }

    $scope.modelsManager = modelsManager;

    $scope.cubeConfig = cubeConfig;

    $scope.getPartitonColumns = function(tableName){
        var columns = _.filter($scope.getColumnsByTable(tableName),function(column){
            return column.datatype==="date"||column.datatype==="string";
        });
        return columns;
    };

    $scope.getColumnsByTable = function (tableName) {
        var temp = [];
        angular.forEach(TableModel.selectProjectTables, function (table) {
            if (table.name == tableName) {
                temp = table.columns;
            }
        });
        return temp;
    };

    $scope.getColumnType = function (_column,table){
        var columns = $scope.getColumnsByTable(table);
        var type;
        angular.forEach(columns,function(column){
            if(_column === column.name){
                type = column.datatype;
                return;
            }
        });
        return type;
    };

    // ~ Define data
    $scope.state = {
        "modelSchema": "",
        mode:'edit',
        modelName: $scope.routeParams.modelName,
        project:$scope.projectModel.selectedProject
    };

    // ~ init
    if ($scope.isEdit = !!$routeParams.modelName) {

        var modelName = $routeParams.modelName;
        ModelDescService.get({model_name: modelName}, function (model) {
                    if (model) {
                        modelsManager.selectedModel = model;
                        modelsManager.selectedModel.project = ProjectModel.getProjectByCubeModel(modelName);

                        if(!ProjectModel.getSelectedProject()){
                            ProjectModel.setSelectedProject(modelsManager.selectedModel.project);
                            TableModel.aceSrcTbLoaded();
                        }

                        //use
                        //convert GMT mills ,to make sure partition date show GMT Date
                        //should run only one time
                        if(model.partition_desc&&model.partition_desc.partition_date_start)
                        {
                            MetaModel.converDateToGMT();
                        }
                    }
                });
        //init project

    } else {
        MetaModel.initModel();
        modelsManager.selectedModel = MetaModel.getMetaModel();
        modelsManager.selectedModel.project = ProjectModel.getSelectedProject();
    }

    $scope.prepareModel = function () {
        // generate column family

        if (modelsManager.selectedModel.partition_desc.partition_date_column!=null&&(modelsManager.selectedModel.partition_desc.partition_date_start|modelsManager.selectedModel.partition_desc.partition_date_start==0)) {
            var dateStart = new Date(modelsManager.selectedModel.partition_desc.partition_date_start);
            dateStart = (dateStart.getFullYear() + "-" + (dateStart.getMonth() + 1) + "-" + dateStart.getDate());
            //switch selected time to utc timestamp
            modelsManager.selectedModel.partition_desc.partition_date_start = new Date(moment.utc(dateStart, "YYYY-MM-DD").format()).getTime();

        }
        if(modelsManager.selectedModel.partition_desc.partition_date_column==null){
            modelsManager.selectedModel.partition_desc.partition_date_start=null;
        }
        $scope.state.project = modelsManager.selectedModel.project;
        var _model = angular.copy(modelsManager.selectedModel);
        delete _model.project;
        $scope.state.modelSchema = angular.toJson(_model, true);

    };

    $scope.modelResultTmpl = function (notification) {
        // Get the static notification template.
        var tmpl = notification.type == 'success' ? 'modelResultSuccess.html' : 'modelResultError.html';
        return $interpolate($templateCache.get(tmpl))(notification);
    };

    $scope.saveModel = function () {

        $scope.prepareModel();

        try {
            angular.fromJson($scope.state.modelSchema);
        } catch (e) {
            SweetAlert.swal('Oops...', 'Invalid model json format..', 'error');
            return;
        }

        SweetAlert.swal({
            title: $scope.isEdit?'Are you sure to update the model?':"Are you sure to save the Model?",
            text: $scope.isEdit?' Please note: if model schema is changed, all cubes of the model will be affected.':'',
            type: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#DD6B55',
            confirmButtonText: "Yes",
            closeOnConfirm: true
        }, function(isConfirm) {
            if(isConfirm){
                loadingRequest.show();

                if ($scope.isEdit) {
                    ModelService.update({}, {modelDescData:$scope.state.modelSchema, modelName: $routeParams.modelName, project: $scope.state.project}, function (request) {
                        if (request.successful) {
                            $scope.state.modelSchema = request.modelSchema;
                            SweetAlert.swal('', 'Updated the model successfully.', 'success');
                            $location.path("/models");
                            //location.reload();
                        } else {
                               $scope.saveModelRollBack();
                                var message =request.message;
                                var msg = !!(message) ? message : 'Failed to take action.';
                                MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        //end loading
                        loadingRequest.hide();
                    }, function (e) {
                        $scope.saveModelRollBack();

                        if(e.data&& e.data.exception){
                            var message =e.data.exception;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            $log.log($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}));
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        } else {
                            MessageService.sendMsg($scope.modelResultTmpl({'text':'Failed to take action.','schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        loadingRequest.hide();
                    });
                } else {
                    ModelService.save({}, {modelDescData:$scope.state.modelSchema, project: $scope.state.project}, function (request) {
                        if(request.successful) {

                          $scope.state.modelSchema = request.modelSchema;
                          SweetAlert.swal('', 'Created the model successfully.', 'success');
                          $location.path("/models");
                          location.reload();
                        } else {
                            $scope.saveModelRollBack();
                            var message =request.message;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }

                        //end loading
                        loadingRequest.hide();
                    }, function (e) {
                        $scope.saveModelRollBack();

                        if (e.data && e.data.exception) {
                            var message =e.data.exception;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        } else {
                            MessageService.sendMsg($scope.modelResultTmpl({'text':"Failed to take action.",'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        //end loading
                        loadingRequest.hide();

                    });
                }
            }
            else{
                $scope.saveModelRollBack();
            }
        });
    };

//    reverse the date
    $scope.saveModelRollBack = function (){
        if(modelsManager.selectedModel.partition_desc.partition_date_start==0){
            modelsManager.selectedModel.partition_desc.partition_date_start = null;
        }
        if(modelsManager.selectedModel&&(modelsManager.selectedModel.partition_desc.partition_date_start||modelsManager.selectedModel.partition_desc.partition_date_start==0))
        {
            modelsManager.selectedModel.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
        }
    };

    $scope.removeTableDimensions = function(tableIndex){
        modelsManager.selectedModel.dimensions.splice(tableIndex,1);
    }

    $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
        if(!newValue){
            return;
        }
        var param = {
            ext: true,
            project:newValue
        };
        if(newValue){
            TableModel.initTables();
            TableService.list(param, function (tables) {
                angular.forEach(tables, function (table) {
                    table.name = table.database+"."+table.name;
                    TableModel.addTable(table);
                });
            });
        }
    });
});
<commit_msg>KYLIN-794 support timestamp type column as partition column on GUI<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

'use strict';

KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $location, $templateCache, $interpolate, MessageService, TableService, CubeDescService, ModelService, loadingRequest, SweetAlert,$log,cubeConfig,CubeDescModel,ModelDescService,MetaModel,TableModel,ProjectService,ProjectModel,modelsManager) {
    //add or edit ?
    var absUrl = $location.absUrl();
    $scope.modelMode = absUrl.indexOf("/models/add")!=-1?'addNewModel':absUrl.indexOf("/models/edit")!=-1?'editExistModel':'default';

    if($scope.modelMode=="addNewModel"&&!ProjectModel.getSelectedProject()){
        SweetAlert.swal('Oops...', 'Please select your project first.', 'warning');
        $location.path("/models");
    }

    $scope.modelsManager = modelsManager;

    $scope.cubeConfig = cubeConfig;

    $scope.getPartitonColumns = function(tableName){
        var columns = _.filter($scope.getColumnsByTable(tableName),function(column){
            return column.datatype==="date"||column.datatype==="string"||column.datatype==="timestamp";
        });
        return columns;
    };

    $scope.getColumnsByTable = function (tableName) {
        var temp = [];
        angular.forEach(TableModel.selectProjectTables, function (table) {
            if (table.name == tableName) {
                temp = table.columns;
            }
        });
        return temp;
    };

    $scope.getColumnType = function (_column,table){
        var columns = $scope.getColumnsByTable(table);
        var type;
        angular.forEach(columns,function(column){
            if(_column === column.name){
                type = column.datatype;
                return;
            }
        });
        return type;
    };

    // ~ Define data
    $scope.state = {
        "modelSchema": "",
        mode:'edit',
        modelName: $scope.routeParams.modelName,
        project:$scope.projectModel.selectedProject
    };

    // ~ init
    if ($scope.isEdit = !!$routeParams.modelName) {

        var modelName = $routeParams.modelName;
        ModelDescService.get({model_name: modelName}, function (model) {
                    if (model) {
                        modelsManager.selectedModel = model;
                        modelsManager.selectedModel.project = ProjectModel.getProjectByCubeModel(modelName);

                        if(!ProjectModel.getSelectedProject()){
                            ProjectModel.setSelectedProject(modelsManager.selectedModel.project);
                            TableModel.aceSrcTbLoaded();
                        }

                        //use
                        //convert GMT mills ,to make sure partition date show GMT Date
                        //should run only one time
                        if(model.partition_desc&&model.partition_desc.partition_date_start)
                        {
                            MetaModel.converDateToGMT();
                        }
                    }
                });
        //init project

    } else {
        MetaModel.initModel();
        modelsManager.selectedModel = MetaModel.getMetaModel();
        modelsManager.selectedModel.project = ProjectModel.getSelectedProject();
    }

    $scope.prepareModel = function () {
        // generate column family

        if (modelsManager.selectedModel.partition_desc.partition_date_column!=null&&(modelsManager.selectedModel.partition_desc.partition_date_start|modelsManager.selectedModel.partition_desc.partition_date_start==0)) {
            var dateStart = new Date(modelsManager.selectedModel.partition_desc.partition_date_start);
            dateStart = (dateStart.getFullYear() + "-" + (dateStart.getMonth() + 1) + "-" + dateStart.getDate());
            //switch selected time to utc timestamp
            modelsManager.selectedModel.partition_desc.partition_date_start = new Date(moment.utc(dateStart, "YYYY-MM-DD").format()).getTime();

        }
        if(modelsManager.selectedModel.partition_desc.partition_date_column==null){
            modelsManager.selectedModel.partition_desc.partition_date_start=null;
        }
        $scope.state.project = modelsManager.selectedModel.project;
        var _model = angular.copy(modelsManager.selectedModel);
        delete _model.project;
        $scope.state.modelSchema = angular.toJson(_model, true);

    };

    $scope.modelResultTmpl = function (notification) {
        // Get the static notification template.
        var tmpl = notification.type == 'success' ? 'modelResultSuccess.html' : 'modelResultError.html';
        return $interpolate($templateCache.get(tmpl))(notification);
    };

    $scope.saveModel = function () {

        $scope.prepareModel();

        try {
            angular.fromJson($scope.state.modelSchema);
        } catch (e) {
            SweetAlert.swal('Oops...', 'Invalid model json format..', 'error');
            return;
        }

        SweetAlert.swal({
            title: $scope.isEdit?'Are you sure to update the model?':"Are you sure to save the Model?",
            text: $scope.isEdit?' Please note: if model schema is changed, all cubes of the model will be affected.':'',
            type: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#DD6B55',
            confirmButtonText: "Yes",
            closeOnConfirm: true
        }, function(isConfirm) {
            if(isConfirm){
                loadingRequest.show();

                if ($scope.isEdit) {
                    ModelService.update({}, {modelDescData:$scope.state.modelSchema, modelName: $routeParams.modelName, project: $scope.state.project}, function (request) {
                        if (request.successful) {
                            $scope.state.modelSchema = request.modelSchema;
                            SweetAlert.swal('', 'Updated the model successfully.', 'success');
                            $location.path("/models");
                            //location.reload();
                        } else {
                               $scope.saveModelRollBack();
                                var message =request.message;
                                var msg = !!(message) ? message : 'Failed to take action.';
                                MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        //end loading
                        loadingRequest.hide();
                    }, function (e) {
                        $scope.saveModelRollBack();

                        if(e.data&& e.data.exception){
                            var message =e.data.exception;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            $log.log($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}));
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        } else {
                            MessageService.sendMsg($scope.modelResultTmpl({'text':'Failed to take action.','schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        loadingRequest.hide();
                    });
                } else {
                    ModelService.save({}, {modelDescData:$scope.state.modelSchema, project: $scope.state.project}, function (request) {
                        if(request.successful) {

                          $scope.state.modelSchema = request.modelSchema;
                          SweetAlert.swal('', 'Created the model successfully.', 'success');
                          $location.path("/models");
                          location.reload();
                        } else {
                            $scope.saveModelRollBack();
                            var message =request.message;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }

                        //end loading
                        loadingRequest.hide();
                    }, function (e) {
                        $scope.saveModelRollBack();

                        if (e.data && e.data.exception) {
                            var message =e.data.exception;
                            var msg = !!(message) ? message : 'Failed to take action.';
                            MessageService.sendMsg($scope.modelResultTmpl({'text':msg,'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        } else {
                            MessageService.sendMsg($scope.modelResultTmpl({'text':"Failed to take action.",'schema':$scope.state.modelSchema}), 'error', {}, true, 'top_center');
                        }
                        //end loading
                        loadingRequest.hide();

                    });
                }
            }
            else{
                $scope.saveModelRollBack();
            }
        });
    };

//    reverse the date
    $scope.saveModelRollBack = function (){
        if(modelsManager.selectedModel.partition_desc.partition_date_start==0){
            modelsManager.selectedModel.partition_desc.partition_date_start = null;
        }
        if(modelsManager.selectedModel&&(modelsManager.selectedModel.partition_desc.partition_date_start||modelsManager.selectedModel.partition_desc.partition_date_start==0))
        {
            modelsManager.selectedModel.partition_desc.partition_date_start+=new Date().getTimezoneOffset()*60000;
        }
    };

    $scope.removeTableDimensions = function(tableIndex){
        modelsManager.selectedModel.dimensions.splice(tableIndex,1);
    }

    $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) {
        if(!newValue){
            return;
        }
        var param = {
            ext: true,
            project:newValue
        };
        if(newValue){
            TableModel.initTables();
            TableService.list(param, function (tables) {
                angular.forEach(tables, function (table) {
                    table.name = table.database+"."+table.name;
                    TableModel.addTable(table);
                });
            });
        }
    });
});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter(function(product){
        return !product.containsNuts && !_(product.ingredients).any(function(ingredient){
          return ingredient === "mushrooms";
        });
      });

      console.log(productsICanEat);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.range(0,1000).filter(function(num){
      return num % 3 === 0 || num % 5 === 0;
    }).reduce(function(memo, num){
      return memo + num;
    }, 0);

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    _.chain(products)
      .map(function(product){ return product.ingredients; })
      .flatten()
      .reduce(function(list, ingredient) {
        ingredientCount[ingredient] = (ingredientCount[ingredient] || 0) + 1;
      })

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  var FILL_ME_IN_TOO = null;

  it("should find the largest prime factor of a composite number", function () {

    var largestPrimeFactorOfComposite = function(compositeNum) {

      var isPrime = function(num) {
        for (var i = 2; i < num; i++) {
          if (num % i === 0) {
            return false;
          }
        }
        return true;
      }

      for (var i = compositeNum; i > 1; i--) {
        if (compositeNum % i === 0 && isPrime(i)) {
          return i;
        }
      }

    };

    expect(largestPrimeFactorOfComposite(25)).toBe(5);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    expect(FILL_ME_IN).toBe(FILL_ME_IN_TOO);
  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    expect(FILL_ME_IN).toBe(FILL_ME_IN_TOO);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    var sumOfSquaresVsSquareOfSums = function(num1, num2) {
      return Math.abs((num1*num1 + num2*num2) - (num1+num2)*(num1+num2));
    }
    expect(sumOfSquaresVsSquareOfSums(3, 4)).toBe(24);
  });

  it("should find the 10001st prime", function () {

    var findNthPrime = function(nthPrime) {

      var isPrime = function(num) {
        for (var i = 2; i < num; i++) {
          if (num % i === 0) {
            return false;
          }
        }
        return true;
      }

      var primeCounter = 1;
      var loopCounter = 2; //the number 2 is the first prime

      while (primeCounter < nthPrime) {
        loopCounter++;

        if (isPrime(loopCounter)) {
          primeCounter++;
        }
      }

      return loopCounter;
    };

    expect(findNthPrime(10001)).toBe(104743);
  });

});
<commit_msg>pseudo-coded solution to largest palindrome from product of two 3-digit nums<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter(function(product){
        return !product.containsNuts && !_(product.ingredients).any(function(ingredient){
          return ingredient === "mushrooms";
        });
      });

      console.log(productsICanEat);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.range(0,1000).filter(function(num){
      return num % 3 === 0 || num % 5 === 0;
    }).reduce(function(memo, num){
      return memo + num;
    }, 0);

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    _.chain(products)
      .map(function(product){ return product.ingredients; })
      .flatten()
      .reduce(function(list, ingredient) {
        ingredientCount[ingredient] = (ingredientCount[ingredient] || 0) + 1;
      })

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  var FILL_ME_IN_TOO = null;

  it("should find the largest prime factor of a composite number", function () {

    var largestPrimeFactorOfComposite = function(compositeNum) {

      var isPrime = function(num) {
        for (var i = 2; i < num; i++) {
          if (num % i === 0) {
            return false;
          }
        }
        return true;
      }

      for (var i = compositeNum; i > 1; i--) {
        if (compositeNum % i === 0 && isPrime(i)) {
          return i;
        }
      }

    };

    expect(largestPrimeFactorOfComposite(25)).toBe(5);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
    //is palindrome function

    //function that descends from highest product down to first palindrome, then returns it
      //999 * 999   998001
      //998 * 999   997002
      //998 * 998   996004
      //997 * 999   996003
      //997 * 998   995006
      //997 * 997   994009

      //outer loop starts at 999
        // inner loop starts at 999 and descends down to outer loop counter
          // checks product to see if its a palindrome, and returns it (first, largest palindrome)
        // IMPLIED: outer loop counter descends once inner loop counter === outer loop counter

    expect(FILL_ME_IN).toBe(FILL_ME_IN_TOO);
  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    expect(FILL_ME_IN).toBe(FILL_ME_IN_TOO);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    var sumOfSquaresVsSquareOfSums = function(num1, num2) {
      return Math.abs((num1*num1 + num2*num2) - (num1+num2)*(num1+num2));
    }
    expect(sumOfSquaresVsSquareOfSums(3, 4)).toBe(24);
  });

  it("should find the 10001st prime", function () {

    var findNthPrime = function(nthPrime) {

      var isPrime = function(num) {
        for (var i = 2; i < num; i++) {
          if (num % i === 0) {
            return false;
          }
        }
        return true;
      }

      var primeCounter = 1;
      var loopCounter = 2; //the number 2 is the first prime

      while (primeCounter < nthPrime) {
        loopCounter++;

        if (isPrime(loopCounter)) {
          primeCounter++;
        }
      }

      return loopCounter;
    };

    expect(findNthPrime(10001)).toBe(104743);
  });

});
<|endoftext|>


<commit_before>"use strict";

var oTable;
var colHdrs = [];       // e.g: ['sTitle': 'Testcase', 'sTitle': 'Env', ... ]
var rowHdrs = [];       // e.g: ['mixed-2suv', 'lucky6', ...]
var baselines = [];
var WARNING_RANGE = 0.1;
var ERROR_RANGE = 0.3;           // TODO: user define

function createSettings() {
    /*
     * Create user setting table
     *
     * The first two columns are reserved for build infos and timestamps
     * Actual settings starts from column 3
     */
    var buildList = '';
    var content = '';

    $.each(colHdrs.slice(2), function(j, build) {
        buildList += '<option value="' + build.sTitle + '">';
        buildList +=  build.sTitle + '</option>';
    });

    $.each(rowHdrs, function(i, metric) {
        content += '
' + metric + '	';
        content += '<select>' + buildList + '</select>
';
    });

    return content;
}

function saveSettings() {
    /*
     * Save user defined settings to cookie
     */
    $('#settings table tbody tr').each(function(i) {
        var col = $(this).find('td').eq(0).text();
        var build = $(this).find("select option:selected").text();
        $.cookie(col, build, { expires: 14 });
        oTable.$('tr').each(function() {
            var row = oTable.fnGetData(this);
            if (row[0] === build) {
                baselines[i] = parseInt(row[2+i]);
            }
        });
    });
}

function getSettings() {
    /*
     * Get user defined settings
     */
    $('#settings table tbody tr').each(function(i) {
        var col = $(this).find('td').eq(0).text();
        var build = $.cookie(col);
        if (build !== null) {
            $(this).find('select option').filter(function() {
                return $(this).text() === build;
            }).attr('selected', true);
        } else {
            build = $(this).find("select option:selected").text();
        }
        oTable.$('tr').each(function() {
            var row = oTable.fnGetData(this);
            if (row[0] === build) {
                baselines[i] = parseInt(row[2+i]);
            }
        });
    });
}

function applyErrorRanges() {
    /*
     * Apply error range check for each cell
     *
     * If data falls out of the range, turns cell to red
     * Accept negative ranges
     */
    oTable.$('tr').each(function() {
        var row = $(this);
        var vals = oTable.fnGetData(this);
        $.each(vals.slice(2), function(j, v) {
            v = parseInt(v);
            $(row).find('td').eq(j+2).removeAttr("style");
            if (!isNaN(baselines[j]) && !isNaN(v)) {
                var delta = (v - baselines[j]) / baselines[j];
                if (Math.abs(ERROR_RANGE) < Math.abs(WARNING_RANGE)) {
                    console.log("invalid error/warning ranges");
                    return;
                }
                if ((delta > ERROR_RANGE && ERROR_RANGE > 0) ||
                    (delta < ERROR_RANGE && ERROR_RANGE < 0)) {
                    $(row).find('td').eq(j+2).css("background-color","red");
                } else if ((delta > WARNING_RANGE && delta < ERROR_RANGE) ||
                           (delta < WARNING_RANGE && delta > ERROR_RANGE)) {
                    $(row).find('td').eq(j+2).css("background-color","yellow");
                }
            }
        });
    });
}

function processData(data) {
    /*
     * Process json data coming from the server
     * Current implementation retrieves info only
     */
    $.each(data[0], function(i, v) {
        colHdrs[i] = {'sTitle': v};
    });

    $.each(data.slice(1), function(i, v) {
        rowHdrs[i] = v[0];
    });

    return data;
}

function renderTable(data) {
    /*
     * Render table with the given data
     */

    oTable = $('#litmus table').dataTable({
        "sDom": 'Tlfrtip',
        'bProcessing': true,
        'bPaginate': true,
        'sPaginationType': 'full_numbers',
        'aaData': data.slice(1),
        'aoColumns': colHdrs,
        'aaSorting': [[0, 'desc']],
        'bStateSave': true,
        'fnDrawCallback': function() {
            $('#loading').remove();
        }
    }).bind('sort', function () {
        applyErrorRanges();
    });

    oTable.$('td').each(function() {
        var pos = oTable.fnGetPosition(this);
        if (pos[1] < 4) {
            return;     // support test results for now
        }
        var testcase= data[pos[0] + 1][0];
        var env = data[pos[0] + 1][1];
        var metric = data[pos[0] + 1][2];
        var build = colHdrs[pos[1]]['sTitle'];
        $(this).qtip({
            content: {
                text: 'Loading...',
                ajax: {
                    url: '../get/comment',
                    type: 'GET',
                    loading: false,
                    data: {'testcase': testcase,
                           'env': env,
                           'build': build,
                           'metric': metric},
                    success: function(data, status) {
                        if ($.trim(data).length === 0) {
                            this.set('content.text', 'Click to edit comment');
                        } else {
                            this.set('content.text', data);
                        }
                    }
                }
            },
            position: {
                at: 'bottom center',
                my: 'top left'
            },
            show: {
                solo: true
            },
            hide: 'unfocus',
            style: {
                classes: 'qtip-shadow'
            },
            events: {
                focus: function(event, api) {
                    $(this).find('.qtip-content').editable( '../post/comment/', {
                        submitdata: function (value, settings) {
                            return {
                                "testcase": testcase,
                                "env": env,
                                "metric": metric,
                                "build": build,
                                "comment": $('input[name=value]').val()
                            };
                        },
                        height: '14px',
                        width: '100%'
                    });
                }
            }
        });
    });

    new FixedHeader(oTable);
}
<commit_msg>show proper messages for ajax error<commit_after>"use strict";

var oTable;
var colHdrs = [];       // e.g: ['sTitle': 'Testcase', 'sTitle': 'Env', ... ]
var rowHdrs = [];       // e.g: ['mixed-2suv', 'lucky6', ...]
var baselines = [];
var WARNING_RANGE = 0.1;
var ERROR_RANGE = 0.3;           // TODO: user define

function createSettings() {
    /*
     * Create user setting table
     *
     * The first two columns are reserved for build infos and timestamps
     * Actual settings starts from column 3
     */
    var buildList = '';
    var content = '';

    $.each(colHdrs.slice(2), function(j, build) {
        buildList += '<option value="' + build.sTitle + '">';
        buildList +=  build.sTitle + '</option>';
    });

    $.each(rowHdrs, function(i, metric) {
        content += '
' + metric + '	';
        content += '<select>' + buildList + '</select>
';
    });

    return content;
}

function saveSettings() {
    /*
     * Save user defined settings to cookie
     */
    $('#settings table tbody tr').each(function(i) {
        var col = $(this).find('td').eq(0).text();
        var build = $(this).find("select option:selected").text();
        $.cookie(col, build, { expires: 14 });
        oTable.$('tr').each(function() {
            var row = oTable.fnGetData(this);
            if (row[0] === build) {
                baselines[i] = parseInt(row[2+i]);
            }
        });
    });
}

function getSettings() {
    /*
     * Get user defined settings
     */
    $('#settings table tbody tr').each(function(i) {
        var col = $(this).find('td').eq(0).text();
        var build = $.cookie(col);
        if (build !== null) {
            $(this).find('select option').filter(function() {
                return $(this).text() === build;
            }).attr('selected', true);
        } else {
            build = $(this).find("select option:selected").text();
        }
        oTable.$('tr').each(function() {
            var row = oTable.fnGetData(this);
            if (row[0] === build) {
                baselines[i] = parseInt(row[2+i]);
            }
        });
    });
}

function applyErrorRanges() {
    /*
     * Apply error range check for each cell
     *
     * If data falls out of the range, turns cell to red
     * Accept negative ranges
     */
    oTable.$('tr').each(function() {
        var row = $(this);
        var vals = oTable.fnGetData(this);
        $.each(vals.slice(2), function(j, v) {
            v = parseInt(v);
            $(row).find('td').eq(j+2).removeAttr("style");
            if (!isNaN(baselines[j]) && !isNaN(v)) {
                var delta = (v - baselines[j]) / baselines[j];
                if (Math.abs(ERROR_RANGE) < Math.abs(WARNING_RANGE)) {
                    console.log("invalid error/warning ranges");
                    return;
                }
                if ((delta > ERROR_RANGE && ERROR_RANGE > 0) ||
                    (delta < ERROR_RANGE && ERROR_RANGE < 0)) {
                    $(row).find('td').eq(j+2).css("background-color","red");
                } else if ((delta > WARNING_RANGE && delta < ERROR_RANGE) ||
                           (delta < WARNING_RANGE && delta > ERROR_RANGE)) {
                    $(row).find('td').eq(j+2).css("background-color","yellow");
                }
            }
        });
    });
}

function processData(data) {
    /*
     * Process json data coming from the server
     * Current implementation retrieves info only
     */
    $.each(data[0], function(i, v) {
        colHdrs[i] = {'sTitle': v};
    });

    $.each(data.slice(1), function(i, v) {
        rowHdrs[i] = v[0];
    });

    return data;
}

function renderTable(data) {
    /*
     * Render table with the given data
     */

    oTable = $('#litmus table').dataTable({
        "sDom": 'Tlfrtip',
        'bProcessing': true,
        'bPaginate': true,
        'sPaginationType': 'full_numbers',
        'aaData': data.slice(1),
        'aoColumns': colHdrs,
        'aaSorting': [[0, 'desc']],
        'bStateSave': true,
        'fnDrawCallback': function() {
            $('#loading').remove();
        }
    }).bind('sort', function () {
        applyErrorRanges();
    });

    oTable.$('td').each(function() {
        var pos = oTable.fnGetPosition(this);
        if (pos[1] < 4) {
            return;     // support test results for now
        }
        var testcase= data[pos[0] + 1][0];
        var env = data[pos[0] + 1][1];
        var metric = data[pos[0] + 1][2];
        var build = colHdrs[pos[1]]['sTitle'];
        $(this).qtip({
            content: {
                text: 'Loading...',
                ajax: {
                    url: '../get/comment',
                    type: 'GET',
                    loading: false,
                    data: {'testcase': testcase,
                           'env': env,
                           'build': build,
                           'metric': metric},
                    success: function(data, status) {
                        if ($.trim(data).length === 0) {
                            this.set('content.text', 'Click to edit comment');
                        } else {
                            this.set('content.text', data);
                        }
                    },
                    error: function(response) {
                        console.error(response.responseText);
                        this.set('content.text', 'Click to edit comment');
                    }
                }
            },
            position: {
                at: 'bottom center',
                my: 'top left'
            },
            show: {
                solo: true
            },
            hide: 'unfocus',
            style: {
                classes: 'qtip-shadow'
            },
            events: {
                focus: function(event, api) {
                    $(this).find('.qtip-content').editable( '../post/comment/', {
                        submitdata: function (value, settings) {
                            return {
                                "testcase": testcase,
                                "env": env,
                                "metric": metric,
                                "build": build,
                                "comment": $('input[name=value]').val()
                            };
                        },
                        height: '14px',
                        width: '100%'
                    });
                }
            }
        });
    });

    new FixedHeader(oTable);
}
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter( function(prod){
                  return !prod.containsNuts && _(prod.ingredients).all(function(i){
                  return i !== 'mushrooms';});
            })

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum =  _.chain(_.range(1, 1000))
                .filter(function(x){return x%3===0 || x%5 ===0;})
                .reduce(function (total, num) {return total+= num;})
                .value();
    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    ingredientCount = _.chain(products)
                  .map(function(po))
                  .flatten()
                  .reduce()
                  .value()
    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>chain done<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter( function(prod){
                  return !prod.containsNuts && _(prod.ingredients).all(function(i){
                  return i !== 'mushrooms';});
            })

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum =  _.chain(_.range(1, 1000))
                .filter(function(x){return x%3===0 || x%5 ===0;})
                .reduce(function (total, num) {return total+= num;})
                .value();
    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
  ingredientCount = _.chain(products)
                  .map(function(x){ return x.ingredients;},{})
                  .flatten()
                  .filter()
                  .reduce(function(n, x){
                    ingredientCount[x] = (ingredientCount[x] || 0) + 1;
                  n = ingredientCount;
                  return n;
                       })
                  .value();
    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>// Write dummy files
/*
for (i=0; i<6; i++) {
    var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'jambon'+i+'.wav');
    f.write('something inside jambon file');
}
*/

// mock recorder made for testing on simulator
var VR_MOCK = {
    recording: false,
    start: function() {
		this.recording=true;
		Ti.API.info('recorder.START');
	},
    stop: function() {
    	this.recording=false;
    	Ti.API.info('recorder.STOP');
    	var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'jambon1.wav');

    	return file;
    },
    compression: Ti.Media.AUDIO_FORMAT_ULAW,
    format: Ti.Media.AUDIO_FILEFORMAT_WAVE
};
////////////////////

if (Ti.version < 1.8 ) {
	alert('Sorry - this application template requires Titanium Mobile SDK 1.8 or later');
}

// User interface (UI) construction
var win = Ti.UI.createWindow({
	backgroundColor: '#ffffff',
	title: 'Sili',
	layout: 'vertical'
});

var headerView = Ti.UI.createView({
	height: '10%',
	width: '100%',
	backgroundColor: '#002EB8'
});

headerView.add(Ti.UI.createLabel({
	text: 'Sili',
	left: 7,
	color: '#ffffff',
    height: Ti.UI.FILL,
    verticalAlign: Ti.UI.TEXT_VERTICAL_ALIGNMENT_CENTER,
    font:{
		fontSize: '22sp',
		fontWeight: 'bold'
	}
}));

var edit = Titanium.UI.createButton({
	title: 'Edit',
	right: 5,
	visible: true
});

var done = Titanium.UI.createButton({
	title: 'Done',
	right: 5,
	visible: false
});

headerView.add(edit);
headerView.add(done);

win.add(headerView);

var recordingsView = Ti.UI.createView({
	height: '65%',
	width: '100%'
});

var table = Ti.UI.createTableView({
	width: Ti.UI.FILL,
	height: Ti.UI.FILL,
	editable: true
});

recordingsView.add(table);
win.add(recordingsView);

var buttonView = Ti.UI.createView({
	width: '100%',
	height: '25%',
	backgroundColor: '#404040',
	bottom: 0
});

var recordButton = Ti.UI.createImageView({
	image: '/images/recording_off.png',
	height: '95%'
});

buttonView.add(recordButton);

win.add(buttonView);

// Make Table view editable to allow file deletion.
edit.addEventListener('click', function(e) {
	toggleEditMode();
});

done.addEventListener('click', function() {
	toggleEditMode();
});

function toggleEditMode() {
	edit.visible = !edit.visible;
	done.visible = !done.visible;
	table.editing = !table.editing;
}

// Table view events
table.addEventListener('click', function(e) {
	sound = Ti.Media.createSound({ url: e.rowData.fileName });
	sound.play();
});

table.addEventListener('delete', function(e) {
	var fileToDelete = Ti.Filesystem.getFile(e.rowData.fileName);

	Titanium.API.info("deleting file= " +  JSON.stringify(fileToDelete));
	fileToDelete.deleteFile();
});

// Load the table view with previously recorded audio files
loadExixtingAudioFiles();

// Record audio file
Ti.Media.audioSessionMode = Ti.Media.AUDIO_SESSION_MODE_PLAY_AND_RECORD;

//var recorder = Ti.Media.createAudioRecorder(); // For on device testing
var recorder = VR_MOCK; // For Simulator testing (won't work, but allows to test UI)
recorder.compression = Ti.Media.AUDIO_FORMAT_ULAW;
recorder.format = Ti.Media.AUDIO_FILEFORMAT_WAVE;

recordButton.addEventListener('click', function(e) {
	if (recorder.recording) {
		var buffer = recorder.stop();
		var newFile =Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, buffer.createTimestamp() + '.wav');

		newFile.write(buffer);

		table.setData([]);
		loadExixtingAudioFiles();

		e.source.image = '/images/recording_off.png';
	} else {
		recorder.start();
		e.source.image = '/images/recording_on.png';
	}
});

win.open();

function loadExixtingAudioFiles() {
	// Read the audio files from device
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory);
	var files = f.getDirectoryListing();
	var tableData = []

	for (var i = 0; i < files.length; i++) {
		var recording = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, files[i]);
		var recordingTimestamp = new Date(recording.createTimestamp());
		var rowLabel = String.formatDate(recordingTimestamp, 'medium') + ' - ' + String.formatTime(recordingTimestamp);

		var row = Ti.UI.createTableViewRow({
			title: rowLabel,
			leftImage: '/images/tape.png',
			color: '#404040',
			className: 'lap',
			font:{
				fontSize: '24sp',
				fontWeight: 'bold'
			},
			fileName: Ti.Filesystem.applicationDataDirectory + '/' + recording.name
		});
		tableData.push(row);
	}

	table.setData(tableData);
}<commit_msg>renamed class name<commit_after>// Write dummy files
/*
for (i=0; i<6; i++) {
    var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'jambon'+i+'.wav');
    f.write('something inside jambon file');
}
*/

// mock recorder made for testing on simulator
var VR_MOCK = {
    recording: false,
    start: function() {
		this.recording=true;
		Ti.API.info('recorder.START');
	},
    stop: function() {
    	this.recording=false;
    	Ti.API.info('recorder.STOP');
    	var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'jambon1.wav');

    	return file;
    },
    compression: Ti.Media.AUDIO_FORMAT_ULAW,
    format: Ti.Media.AUDIO_FILEFORMAT_WAVE
};
////////////////////

if (Ti.version < 1.8 ) {
	alert('Sorry - this application template requires Titanium Mobile SDK 1.8 or later');
}

// User interface (UI) construction
var win = Ti.UI.createWindow({
	backgroundColor: '#ffffff',
	title: 'Sili',
	layout: 'vertical'
});

var headerView = Ti.UI.createView({
	height: '10%',
	width: '100%',
	backgroundColor: '#002EB8'
});

headerView.add(Ti.UI.createLabel({
	text: 'Sili',
	left: 7,
	color: '#ffffff',
    height: Ti.UI.FILL,
    verticalAlign: Ti.UI.TEXT_VERTICAL_ALIGNMENT_CENTER,
    font:{
		fontSize: '22sp',
		fontWeight: 'bold'
	}
}));

var edit = Titanium.UI.createButton({
	title: 'Edit',
	right: 5,
	visible: true
});

var done = Titanium.UI.createButton({
	title: 'Done',
	right: 5,
	visible: false
});

headerView.add(edit);
headerView.add(done);

win.add(headerView);

var recordingsView = Ti.UI.createView({
	height: '65%',
	width: '100%'
});

var table = Ti.UI.createTableView({
	width: Ti.UI.FILL,
	height: Ti.UI.FILL,
	editable: true
});

recordingsView.add(table);
win.add(recordingsView);

var buttonView = Ti.UI.createView({
	width: '100%',
	height: '25%',
	backgroundColor: '#404040',
	bottom: 0
});

var recordButton = Ti.UI.createImageView({
	image: '/images/recording_off.png',
	height: '95%'
});

buttonView.add(recordButton);

win.add(buttonView);

// Make Table view editable to allow file deletion.
edit.addEventListener('click', function(e) {
	toggleEditMode();
});

done.addEventListener('click', function() {
	toggleEditMode();
});

function toggleEditMode() {
	edit.visible = !edit.visible;
	done.visible = !done.visible;
	table.editing = !table.editing;
}

// Table view events
table.addEventListener('click', function(e) {
	sound = Ti.Media.createSound({ url: e.rowData.fileName });
	sound.play();
});

table.addEventListener('delete', function(e) {
	var fileToDelete = Ti.Filesystem.getFile(e.rowData.fileName);

	Titanium.API.info("deleting file= " +  JSON.stringify(fileToDelete));
	fileToDelete.deleteFile();
});

// Load the table view with previously recorded audio files
loadExixtingAudioFiles();

// Record audio file
Ti.Media.audioSessionMode = Ti.Media.AUDIO_SESSION_MODE_PLAY_AND_RECORD;

//var recorder = Ti.Media.createAudioRecorder(); // For on device testing
var recorder = VR_MOCK; // For Simulator testing (won't work, but allows to test UI)
recorder.compression = Ti.Media.AUDIO_FORMAT_ULAW;
recorder.format = Ti.Media.AUDIO_FILEFORMAT_WAVE;

recordButton.addEventListener('click', function(e) {
	if (recorder.recording) {
		var buffer = recorder.stop();
		var newFile =Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, buffer.createTimestamp() + '.wav');

		newFile.write(buffer);

		table.setData([]);
		loadExixtingAudioFiles();

		e.source.image = '/images/recording_off.png';
	} else {
		recorder.start();
		e.source.image = '/images/recording_on.png';
	}
});

win.open();

function loadExixtingAudioFiles() {
	// Read the audio files from device
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory);
	var files = f.getDirectoryListing();
	var tableData = []

	for (var i = 0; i < files.length; i++) {
		var recording = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, files[i]);
		var recordingTimestamp = new Date(recording.createTimestamp());
		var rowLabel = String.formatDate(recordingTimestamp, 'medium') + ' - ' + String.formatTime(recordingTimestamp);

		var row = Ti.UI.createTableViewRow({
			title: rowLabel,
			leftImage: '/images/tape.png',
			color: '#404040',
			className: 'recording',
			font:{
				fontSize: '24sp',
				fontWeight: 'bold'
			},
			fileName: Ti.Filesystem.applicationDataDirectory + '/' + recording.name
		});
		tableData.push(row);
	}

	table.setData(tableData);
}<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter(function(prod)
      {
        var isNotShroom = function(ingred) {
          return ingred === 'mushrooms' ? false : true;
        };
        if(!prod.containsNuts && _(prod.ingredients).all(isNotShroom)) {
          return true;
        }
      });

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var isMultipleOfThreeOrFive = function(num) {
      if(num % 3 === 0 || num % 5 === 0) {
        return true;
      } else return false;
    };

    var sumNums = function(memo, x) { return memo + x; };

    /* try chaining range() and reduce() */
    var sum = _(_.range(1000)).chain()
                  .filter(isMultipleOfThreeOrFive)
                  .reduce(sumNums, 0)
                  .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            // console.log(ingredientCount[products[i].ingredients[j]]);
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    // console.log(ingredientCount);

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var countIngredients = function(memo, x) {
      memo[x] = (memo[x] || 0) + 1;
      return memo;
    };

    /* chain() together map(), flatten() and reduce() */
    ingredientCount = _(products).chain()
                          .map(function(x) { return x.ingredients; })
                          .flatten()
                          .reduce(countIngredients, ingredientCount)
                          .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {
    var compositeNum = 38;

    var isPrime = function(n) {
      var test = true;
      var checkRange = _.range(2, n);
      checkRange.forEach(function(x) {
        if(n % x === 0) test = false;
      });
      return test;
    };

    var findGreaterPrime = function(memo, z) {
      if(isPrime(z) && z > memo) memo = z;
      return memo;
    };

    var largestPrimeFactor = _(_.range(2, (compositeNum / 2) + 1)).chain()
                                  .filter(function(x) { return compositeNum % x === 0; })
                                  .reduce(findGreaterPrime, 2)
                                  .value();

    expect(largestPrimeFactor).toBe(19);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    var isPalindrome = function(num) {
      num = num.toString().split('');
      var reverseNum = num.slice().reverse();
      return num.join('') === reverseNum.join('') ? true : false;
    };

    var hasTwoThreeDigitFactors = function(num) {
      var highestPossFact = Math.floor(num / 100);
      var lowestPossFact = Math.floor(num / 999);
      var rangeNums = _.range(highestPossFact, lowestPossFact, -1).filter(function(x) {
        return x > 99 && x < 1000;
      });
      return _(rangeNums).any(function(x) {
        return (num % x === 0 && (num / x).toString().length === 3);
      });
    };

    var palindromList = _(_.range(999 * 999, 100 * 100, -1)).filter(isPalindrome);
    var largestPalendrome = _(palindromList).filter(hasTwoThreeDigitFactors)[0];

    expect(largestPalendrome).toBe(906609);

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    var rangeOneToTwenty = _.range(1, 21);

    var isDivisibleByAllNums = function(num, range) {
      return _(range).reduce(function(memo, x) {
        if(num % x !== 0) {
          memo = false;
        }
        return memo;
      }, true);
    };

    var smallestNumDiv = (function() {
      var counter = 20;
      while(!isDivisibleByAllNums(counter, rangeOneToTwenty)) {
        counter += 20;
      }
      return counter;
    })();

    expect(smallestNumDiv).toBe(232792560);

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

    var getSumSquares = function(rangeArr) {
      return _.reduce(rangeArr, function(memo, x) {
        return memo + Math.pow(x, 2);
      }, 0);
    };

    var getSquareSums = function(rangeArr) {
      return Math.pow(_.reduce(rangeArr, function(memo, x) {return memo + x;}, 0), 2);
    };

    var diffSumSquaresSquareSums = (function(number) {
      var numRange = _.range(1, number + 1);
      return Math.abs(getSumSquares(numRange) - getSquareSums(numRange));
    })(55);

    expect(diffSumSquaresSquareSums).toBe(2314620);

  });

  it("should find the 10001st prime", function () {

  });

});
<commit_msg>completed '10001st prime number' extra credit problem<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter(function(prod)
      {
        var isNotShroom = function(ingred) {
          return ingred === 'mushrooms' ? false : true;
        };
        if(!prod.containsNuts && _(prod.ingredients).all(isNotShroom)) {
          return true;
        }
      });

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var isMultipleOfThreeOrFive = function(num) {
      if(num % 3 === 0 || num % 5 === 0) {
        return true;
      } else return false;
    };

    var sumNums = function(memo, x) { return memo + x; };

    /* try chaining range() and reduce() */
    var sum = _(_.range(1000)).chain()
                  .filter(isMultipleOfThreeOrFive)
                  .reduce(sumNums, 0)
                  .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            // console.log(ingredientCount[products[i].ingredients[j]]);
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    // console.log(ingredientCount);

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var countIngredients = function(memo, x) {
      memo[x] = (memo[x] || 0) + 1;
      return memo;
    };

    /* chain() together map(), flatten() and reduce() */
    ingredientCount = _(products).chain()
                          .map(function(x) { return x.ingredients; })
                          .flatten()
                          .reduce(countIngredients, ingredientCount)
                          .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {
    var compositeNum = 38;

    var isPrime = function(n) {
      var test = true;
      var checkRange = _.range(2, n);
      checkRange.forEach(function(x) {
        if(n % x === 0) test = false;
      });
      return test;
    };

    var findGreaterPrime = function(memo, z) {
      if(isPrime(z) && z > memo) memo = z;
      return memo;
    };

    var largestPrimeFactor = _(_.range(2, (compositeNum / 2) + 1)).chain()
                                  .filter(function(x) { return compositeNum % x === 0; })
                                  .reduce(findGreaterPrime, 2)
                                  .value();

    expect(largestPrimeFactor).toBe(19);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    var isPalindrome = function(num) {
      num = num.toString().split('');
      var reverseNum = num.slice().reverse();
      return num.join('') === reverseNum.join('') ? true : false;
    };

    var hasTwoThreeDigitFactors = function(num) {
      var highestPossFact = Math.floor(num / 100);
      var lowestPossFact = Math.floor(num / 999);
      var rangeNums = _.range(highestPossFact, lowestPossFact, -1).filter(function(x) {
        return x > 99 && x < 1000;
      });
      return _(rangeNums).any(function(x) {
        return (num % x === 0 && (num / x).toString().length === 3);
      });
    };

    var palindromList = _(_.range(999 * 999, 100 * 100, -1)).filter(isPalindrome);
    var largestPalendrome = _(palindromList).filter(hasTwoThreeDigitFactors)[0];

    expect(largestPalendrome).toBe(906609);

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    var rangeOneToTwenty = _.range(1, 21);

    var isDivisibleByAllNums = function(num, range) {
      return _(range).reduce(function(memo, x) {
        if(num % x !== 0) {
          memo = false;
        }
        return memo;
      }, true);
    };

    var smallestNumDiv = (function() {
      var counter = 20;
      while(!isDivisibleByAllNums(counter, rangeOneToTwenty)) {
        counter += 20;
      }
      return counter;
    })();

    expect(smallestNumDiv).toBe(232792560);

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

    var getSumSquares = function(rangeArr) {
      return _.reduce(rangeArr, function(memo, x) {
        return memo + Math.pow(x, 2);
      }, 0);
    };

    var getSquareSums = function(rangeArr) {
      return Math.pow(_.reduce(rangeArr, function(memo, x) {return memo + x;}, 0), 2);
    };

    var diffSumSquaresSquareSums = (function(number) {
      var numRange = _.range(1, number + 1);
      return Math.abs(getSumSquares(numRange) - getSquareSums(numRange));
    })(55);

    expect(diffSumSquaresSquareSums).toBe(2314620);

  });

  it("should find the 10001st prime", function () {

    var isPrime = function(n) {
      var test = true;
      var checkRange = _.range(2, n);
      checkRange.forEach(function(x) {
        if(n % x === 0) test = false;
      });
      return test;
    };

    var getBigPrime = function() {
      var primeCollection = [];
      var counter = 1;
      while(primeCollection.length < 10001) {
        counter++;
        if(isPrime(counter)) {
          primeCollection.push(counter);
        }
      }
      return primeCollection.pop();
    };

    var myBigPrime = getBigPrime();

    expect(myBigPrime).toBe(104743);
  });

});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      var noNuts = function(pizza){
        return pizza.containsNuts === false;
      };

      var noMushroom = function(pizza) {
        return _(pizza.ingredients)
          .all( function(ingredient) {return ingredient !== "mushrooms"} );
      };

      productsICanEat = _(products).filter(noNuts).filter(noMushroom);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.range(1000)
              .reduce(function (sum, x) {
                return (x % 3 === 0 || x % 5 === 0) ? sum + x : sum;
              });

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    var test = _(products).chain()
      .map( function(item){ return item.ingredients; } )
      .flatten()
      // TODO try to reduce instead as suggested
      .each(function (ingredient) {
                ingredientCount[ingredient] = (ingredientCount[ingredient] || 0) + 1;
              })
      .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var factors = function(compositeNumber){
      var results = [];
      var i;
      var max = compositeNumber / 2;
      for(i = 2; i <= max ; i++) {
        if (compositeNumber % i === 0) {
          results.push(i);
        }
      }
      return results;
    };

    var isPrime = function(n) {
      return factors(n).length === 0;
    }

    var largestPrime = function(n) {
      return factors(n).filter(isPrime).pop();
    }

    expect(largestPrime(21)).toBe(7);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
    // A palindrome is a word, or a number, that can be read both from head to end and from end to head
    var isPalindrome = function(number) {
      var toTest = number.toString();
      for (var i = 0; i < Math.floor(toTest.length / 2); i++)
        if (toTest[i] !== toTest[toTest.length - 1 - i]) {
          return false;
        }
      return true;
    };

    var largest = function(){
      for(var i = 999; i > 99; i--) {
        for(var j = 999; j > 99; j--) {
          if (isPalindrome(i*j)){
            return {  "firstNumber" : i,
                      "secondNumber": j,
                      "palindrome": i*j
                    };
          }
        }
      }
    };

    expect(largest().palindrome).toBe(580085);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    var sum = function(a,b) {
      return a + b;
    };

    var square = function(a) {
      return a * a;
    }

    var difference = function(numbers){
      var sumOfSquares = _(numbers)
        .map( function(num){return num*num} )
        .reduce(sum);

      var squareOfSums = square(_(numbers).reduce(sum));

      return squareOfSums - sumOfSquares;
    };

    expect(difference([2,3,4])).toBe(52);
  });

  it("should find the 10001st prime", function () {
  // Useful resource to have some data to check against: https://primes.utm.edu/nthprime

    var factors = function(compositeNumber){
      var results = [];
      var i;
      var max = compositeNumber / 2;
      for(i = 2; i <= max ; i++) {
        if (compositeNumber % i === 0) {
          results.push(i);
        }
      }
      return results;
    };

    var isPrime = function(n) {
      return factors(n).length === 0;
    }

    var primes = [];
    var count = 2;
    while(primes.length < 10001) {
      if (isPrime(count)) {
        primes.push(count);
      }
      count++;
    };

    expect(primes.pop()).toBe(104743);
  });

});
<commit_msg>enlightment!<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      var noNuts = function(pizza){
        return pizza.containsNuts === false;
      };

      var noMushroom = function(pizza) {
        return _(pizza.ingredients)
          .all( function(ingredient) {return ingredient !== "mushrooms"} );
      };

      productsICanEat = _(products).filter(noNuts).filter(noMushroom);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.range(1000)
              .reduce(function (sum, x) {
                return (x % 3 === 0 || x % 5 === 0) ? sum + x : sum;
              });

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    var test = _(products).chain()
      .map( function(item){ return item.ingredients; } )
      .flatten()
      .each(function (ingredient) {
                ingredientCount[ingredient] = (ingredientCount[ingredient] || 0) + 1;
              })
      .value();

    expect(ingredientCount['mushrooms']).toBe(2);

      // reduced version - try to reduce instead as each
      var tester = _(products).chain()
        .map( function(item){ return item.ingredients; } )
        .flatten()
        .reduce(function(ingredientCount, ingredient){
          ingredientCount[ingredient] = (ingredientCount[ingredient] || 0) + 1;
          return ingredientCount;
        }, {})
        .value();

    expect(tester['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var factors = function(compositeNumber){
      var results = [];
      var i;
      var max = compositeNumber / 2;
      for(i = 2; i <= max ; i++) {
        if (compositeNumber % i === 0) {
          results.push(i);
        }
      }
      return results;
    };

    var isPrime = function(n) {
      return factors(n).length === 0;
    }

    var largestPrime = function(n) {
      return factors(n).filter(isPrime).pop();
    }

    expect(largestPrime(21)).toBe(7);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
    // A palindrome is a word, or a number, that can be read both from head to end and from end to head
    var isPalindrome = function(number) {
      var toTest = number.toString();
      for (var i = 0; i < Math.floor(toTest.length / 2); i++)
        if (toTest[i] !== toTest[toTest.length - 1 - i]) {
          return false;
        }
      return true;
    };

    var largest = function(){
      for(var i = 999; i > 99; i--) {
        for(var j = 999; j > 99; j--) {
          if (isPalindrome(i*j)){
            return {  "firstNumber" : i,
                      "secondNumber": j,
                      "palindrome": i*j
                    };
          }
        }
      }
    };

    expect(largest().palindrome).toBe(580085);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    var sum = function(a,b) {
      return a + b;
    };

    var square = function(a) {
      return a * a;
    }

    var difference = function(numbers){
      var sumOfSquares = _(numbers)
        .map( function(num){return num*num} )
        .reduce(sum);

      var squareOfSums = square(_(numbers).reduce(sum));

      return squareOfSums - sumOfSquares;
    };

    expect(difference([2,3,4])).toBe(52);
  });

  it("should find the 10001st prime", function () {
  // Useful resource to have some data to check against: https://primes.utm.edu/nthprime

    var factors = function(compositeNumber){
      var results = [];
      var i;
      var max = compositeNumber / 2;
      for(i = 2; i <= max ; i++) {
        if (compositeNumber % i === 0) {
          results.push(i);
        }
      }
      return results;
    };

    var isPrime = function(n) {
      return factors(n).length === 0;
    }

    var primes = [];
    var count = 2;
    while(primes.length < 10001) {
      if (isPrime(count)) {
        primes.push(count);
      }
      count++;
    };

    expect(primes.pop()).toBe(104743);
  });

});
<|endoftext|>


<commit_before>var path = require('path');
var dirVars = require('../base/dir-vars.config.js');
module.exports = {
  configFile: path.resolve(dirVars.staticRootDir, './.eslintrc'),
  failOnError: true,
};
<commit_msg>eslint开cache<commit_after>var path = require('path');
var dirVars = require('../base/dir-vars.config.js');
module.exports = {
  configFile: path.resolve(dirVars.staticRootDir, './.eslintrc'),
  failOnWarning: true,
  failOnError: true,
  cache: true,
};
<|endoftext|>


<commit_before>const webpack = require('webpack')
const merge = require('webpack-merge')
const str = JSON.stringify
const CommonConfig = require('./common.config.js')

const stylesheet = require('./stylesheet.config')
const uglify = require('./uglify.config')

module.exports = merge(
  CommonConfig,
  stylesheet(),
  uglify(),
  {
    output: {
      publicPath: process.env.RUN_MODE ? '/rs' : '/',
    },
    plugins: [
      new webpack.DefinePlugin({
        __DEV__: false,
        __RUN_MODE__: str(process.env.RUN_MODE || ''),
        __BACKEND_URL__: str(process.env.RUN_MODE ? process.env.BACKEND_URL : 'http://localhost:8080'),
        __WS_URL__: str(process.env.RUN_MODE ? process.env.WS_URL : ''),
        __PACKAGE_SERVER__: str(process.env.PACKAGE_SERVER || process.env.HTML_BASE_URL),
      }),
    ]
  }
)
<commit_msg>change webpack publicPath<commit_after>const webpack = require('webpack')
const merge = require('webpack-merge')
const str = JSON.stringify
const CommonConfig = require('./common.config.js')

const stylesheet = require('./stylesheet.config')
const uglify = require('./uglify.config')

module.exports = merge(
  CommonConfig,
  stylesheet(),
  uglify(),
  {
    output: {
      publicPath: process.env.RUN_MODE ? '/rs2' : '/',
    },
    plugins: [
      new webpack.DefinePlugin({
        __DEV__: false,
        __RUN_MODE__: str(process.env.RUN_MODE || ''),
        __BACKEND_URL__: str(process.env.RUN_MODE ? process.env.BACKEND_URL : 'http://localhost:8080'),
        __WS_URL__: str(process.env.RUN_MODE ? process.env.WS_URL : ''),
        __PACKAGE_SERVER__: str(process.env.PACKAGE_SERVER || process.env.HTML_BASE_URL),
      }),
    ]
  }
)
<|endoftext|>