Non-jewish woman converting for marriage [duplicate]

This question already has an answer here:

  • If a woman converted via Orthodox but had no intention and kept no mitzvoth- are her children jewish

    1 answer

If a non Jewish woman converts in order to marry a Jewish man are their children still considered Jewish? Even though the mother is converted and not raised in the religion

Can you update to macOS 10.14 (Mojave) without converting to APFS?

At WWDC 2018 macOS 10.14 or macOS Mojave was disclosed. I am currently on macOS Sierra (10.12) and am looking forward to upgrading to macOS Mojave once its released. I was wondering if it will be possible to update to macOS Mojave without converting to APFS, similar to this trick from OS X Daily on how to upgrade to macOS High Sierra (10.13) without converting to APFS with the command /Applications/Install macOS High Sierra.app/Contents/Resources/startosinstall --converttoapfs NO.

Converting large GeoJSON to shapefile?

I have recently downloaded a building footprint GeoJSON file from Microsoft Bing Maps. The file I downloaded was for the entirety of Texas, and is of approximately 2.2 GB file size. They do not provide the data in any smaller sections for the state of Texas.

My issue is that I am unable to convert this GeoJSON into any usable format, such as a shapefile. I have tried to use https://mapshaper.org/ but my file size is too large and the website crashes. Similarly, I have tried to open the GeoJSON in QGIS, but that program crashes as well. I know ArcGIS has the Data Interoperability Toolset, but that requires a special license.

Does anyone have any other techniques to convert a large GeoJSON file?

Converting SQL to SOQL

I am transitioning to learning SOQL and am struggling with some basic concepts (specifically, joining tables and using multiple tables in the where clause). Can you help me figure out how the below example SQL would look if converted to SOQL? Or if some of the things just can’t be done? Thanks!

SELECT a.Field1, a.Field2, b.Field3 FROM table1 AS a
LEFT JOIN table2 AS b
ON a.Field1 = b.Field1 AND a.Field2 = b.Field2
WHERE a.Field3 < 100
AND b.Field 3 > 100

Converting employee survey data from CSV to JSON

Github link

This Java code project (Eclipse Photon) was submitted for a job opportunity but was marked down for showing “bad habits that could be difficult to unlearn” but I am mystified by what this means. Any takers please. How could it be approached differently or improved.

I have removed any reference to the company involved, but the challenge was framed this way:

Problem description

An employee survey has been conducted, and you’ve been asked to figure out useful insights
from it. You are given the data as a flat CSV file for all employees across the company,
containing at least the following columns:

divisionId, teamId, managerId, employeeId, firstName, lastName, birthdate

For example, one record (row) of the CSV file looks like the following:

1,7,3,24,Jon,Snow,1986-12-26

Objective

Based on the structure above, write a piece of code which takes the CSV above as input,
and creates a JSON object that looks like the following:

{
 "divisions": {
    "#divisionId": {
        "teams": {
            "#teamId": {
                "managers": {
                    "#managerId": {
                        "employees": {
                            "#employeeId": {
                                "id": "#employeeId",
                                "firstName": "Jon",
                                "lastName": "Snow",
                                "birthdate": "1986-12-26"
                            }
                        }
                    }
                }
            }
        }
    }
 }
}

NOTE: You can find the data set as data.csv in the /data directory.

Questions

  1. What is the big-O runtime complexity of the algorithm you’ve just written?
  2. Can you write the code such that all IDs are in ascending order in the JSON output?
  3. Can you create this such that the list of employees is sorted by their full name?
    (bonus points if you create a mechanism for arbitrary sort order, e.g., variable/multiple
    sort fields, ascending and/or descending order)
  4. [BONUS] Can you calculate the average age across the company, divisions, teams, and managers?

NOTE: for each of the extra questions, you can create different command-line arguments
that changes the mode of the application. However, this is only a suggestion, and are you free
to take any alternative approach you may wish.

Requirements

Unless explicitly requested otherwise, we expect the following to be used:

  • Java 8
  • Gradle as the build system
  • Any necessary libraries (e.g., Jackson for JSON)

Code:

CSVData.Java

package org.challenge.csv;

import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;

/*
 * Base class for CSV data
 *   
 */
public class CSVData {

    private transient final String[] fieldsInCSVHeader;

    protected CSVData(String[] fieldsInCSVHeader) {
        this.fieldsInCSVHeader = fieldsInCSVHeader;
    }

    @JsonIgnore
    public List getHeaderFields() {
        return Arrays.asList(fieldsInCSVHeader);
    }

    public enum SortDirection {
        ASCENDING,
        DESCENDING
    }
}

CSVParser.java

package org.challenge.csv;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.*;

import org.challenge.csv.survey.SurveyCSVParser;
import org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData;

/**
 * Base class for CSV parsers
 *
 */
public class CSVParser {

    private final File csvFile;
    private final short minimumFieldsPerLine;
    private final String seperatorOfFields;

    private List linesOfCSVFile;

    protected CSVParser(File csvFile, short minimumFieldsPerLine, String seperatorOfFields) {
        this.csvFile = csvFile;
        this.minimumFieldsPerLine = minimumFieldsPerLine;
        this.seperatorOfFields = seperatorOfFields;
    }

    public static Parser createSurveyParser(File csvFile, SurveyCSVData.Employee.SortOrder order, CSVData.SortDirection direction) {
        Objects.requireNonNull(csvFile);
        return new SurveyCSVParser(csvFile, order, direction);
    }
    public static Parser createSurveyParser(File csvFile) {
        return new SurveyCSVParser(csvFile, SurveyCSVData.Employee.SortOrder.ORIGINAL, CSVData.SortDirection.ASCENDING);
    }

    protected boolean fileExists() {
        return csvFile.exists() && csvFile.canRead();
    }
    protected boolean fileIsCorrectlyFormatted() {
        readFile();     
        return linesOfCSVFile.size() > 0 && linesOfCSVFile.get(0).split(seperatorOfFields).length >= minimumFieldsPerLine;
    }
    protected List fileLines() {
        readFile();
        return linesOfCSVFile.stream().skip(1).collect(toList());
    }

    private synchronized void readFile()
    {
        try {
            if (null == linesOfCSVFile) {
                if (true == fileExists())
                    linesOfCSVFile = Files.readAllLines(csvFile.toPath());      // NOTE - BufferedReader may be preferred for very large files, can then process line by line or in chunks...
            }
        }
        catch (IOException e) {
            // NOTE - Retry in a limited loop, ...
            throw new RuntimeException("FAILED to read file content");
        }
    }
}

Parser.java

package org.challenge.csv;

import java.util.Optional;

/*
 * Interface defining CSV parser functions
 * 
 */
public interface Parser {
    /**
     * Parse CSV file into an object structure
     * @return CSV data object
     */
    Optional parse();
}

JSONWriter.java

package org.challenge.json;

import org.challenge.csv.CSVData;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;


/**
 * Class for writing JSON data from object graph via Jackson libraries
 *
 */
public final class JSONWriter {

    private final CSVData csvData;

    public JSONWriter(CSVData csvData) {
        this.csvData = csvData;
    }

    public String write() throws JsonProcessingException {

        ObjectMapper objectToJsonMapper = new ObjectMapper();
        String jsonStringRepresentation = objectToJsonMapper.writeValueAsString(csvData);       
        return jsonStringRepresentation;
    }
}

SurveyCSVParser.java

package org.challenge.csv.survey;

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.StringTokenizer;
import java.util.TreeMap;

import org.challenge.csv.CSVData;
import org.challenge.csv.CSVParser;
import org.challenge.csv.Parser;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Class for parsing CSV data related to employee survey
 *
 */
public final class SurveyCSVParser extends CSVParser implements Parser {

    private static final short MIN_TOKENS_PER_LINE = 7;
    private static final String SEPERATOR_OF_TOKENS = ",";

    private final SurveyCSVData.Employee.SortOrder sortOrderOfDataOrEmployees;
    private final CSVData.SortDirection sortDirectionOfEmployees;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d");

    public SurveyCSVParser(File csvFile, SurveyCSVData.Employee.SortOrder sortOrderOfDataOrEmployees, CSVData.SortDirection sortDirectionOfEmployees) {
        super(csvFile, MIN_TOKENS_PER_LINE, SEPERATOR_OF_TOKENS);
        this.sortOrderOfDataOrEmployees = sortOrderOfDataOrEmployees;
        this.sortDirectionOfEmployees = sortDirectionOfEmployees;
    }

    @Override
    public Optional parse() {
        SurveyCSVData csvDataParsed = null;

        if (fileExists() && fileIsCorrectlyFormatted()) {
            List linesOfCSV = fileLines();
            SurveyCSVData csvData = new SurveyCSVData(sortOrderOfDataOrEmployees);
            try {
                if (SurveyCSVData.Employee.SortOrder.ORIGINAL != sortOrderOfDataOrEmployees)
                    linesOfCSV.parallelStream().forEach(l -> processLineOfCSV(l, csvData, sortOrderOfDataOrEmployees, sortDirectionOfEmployees));       
                else
                    linesOfCSV.stream().forEach(l -> processLineOfCSV(l, csvData, sortOrderOfDataOrEmployees, sortDirectionOfEmployees));   
                csvDataParsed = csvData;
            }
            catch (Exception e) {                       
                throw new RuntimeException("FAILED to parse CSV file");     // NOTE - Should a "bad" line prevent the remainder of the parse?
            }
        }

        return Optional.ofNullable(csvDataParsed);
    }

    private static void processLineOfCSV(String line, SurveyCSVData data, SurveyCSVData.Employee.SortOrder sortOrderOfDataOrEmployees, CSVData.SortDirection sortDirectionOfEmployees)
    {
        StringTokenizer tokenizer = new StringTokenizer(line, SEPERATOR_OF_TOKENS);
        short indexOfTokenFound = 0;
        String divisionId = null, teamId = null, managerId = null, employeeId = null, lastName = null, firstName = null, birthdate = null;      
        while (tokenizer.hasMoreTokens() && indexOfTokenFound < MIN_TOKENS_PER_LINE) {

            String token = tokenizer.nextToken();
            switch (indexOfTokenFound) {
                case 0:
                    divisionId = token;
                    break;
                case 1:
                    teamId = token;
                    break;
                case 2:
                    managerId = token;
                    break;
                case 3:
                    employeeId = token;
                    break;
                case 4:
                    firstName = token;
                    break;
                case 5:
                    lastName = token;
                    break;
                case MIN_TOKENS_PER_LINE-1:
                    birthdate = token;
                    break;
                default:
                    assert false;
            }
            indexOfTokenFound++;
        }

        if (indexOfTokenFound >= MIN_TOKENS_PER_LINE)
            buildSurveyData(divisionId, teamId, managerId, employeeId, firstName, lastName, birthdate, data, sortOrderOfDataOrEmployees, sortDirectionOfEmployees);
    }

    private static synchronized void buildSurveyData(String divisionId, String teamId, String managerId, String employeeId, String firstName, String lastName, String birthdate, SurveyCSVData data, SurveyCSVData.Employee.SortOrder sortOrderOfDataOrEmployees, CSVData.SortDirection direction) 
    {
        Objects.requireNonNull(divisionId);
        Objects.requireNonNull(teamId);
        Objects.requireNonNull(managerId);
        Objects.requireNonNull(employeeId);
        Objects.requireNonNull(firstName);
        Objects.requireNonNull(lastName);
        Objects.requireNonNull(birthdate);

        Integer divisionIdBox = Integer.parseInt(divisionId);
        Integer teamIdBox = Integer.parseInt(teamId);
        Integer managerIdBox = Integer.parseInt(managerId);
        Integer employeeIdBox = Integer.parseInt(employeeId);

        if (false == data.divisions.containsKey(divisionIdBox))
             data.divisions.put(divisionIdBox, new SurveyCSVData.Division(divisionIdBox, sortOrderOfDataOrEmployees));
        SurveyCSVData.Division division = data.divisions.get(divisionIdBox);

        if (false == division.teams.containsKey(teamIdBox))
            division.teams.put(teamIdBox, division.createTeam(teamIdBox));
        SurveyCSVData.Team team = division.teams.get(teamIdBox);

        if (false == team.managers.containsKey(managerIdBox))
            team.managers.put(managerIdBox, team.createManager(managerIdBox, direction));
        SurveyCSVData.Manager manager = team.managers.get(managerIdBox);

        if (false == manager.employees.containsKey(employeeIdBox)) 
            manager.employees.put(employeeIdBox, manager.createEmployee(employeeIdBox, firstName, lastName, birthdate));        // NOTE - Duplicates will not be added more than once
    }

    /**
     * 
     * Class representing survey data
     *
     */
    public final static class SurveyCSVData extends CSVData {

        private static final short VERSION = 1;                 // NOTE - Good idea to apply version to data structures

        private Map divisions;

        public SurveyCSVData(Employee.SortOrder sortOrderOfDataOrEmployees) {
            super(new String[] {"divisionId", "teamId", "managerId", "employeeId", "lastName", "firstName", "birthdate"});
            if (Employee.SortOrder.ORIGINAL == sortOrderOfDataOrEmployees)
                divisions = new LinkedHashMap <>();
            else
                divisions = new TreeMap<>();
        }

        public void addDivision(Integer id, Division division) {
            Objects.requireNonNull(id); Objects.requireNonNull(division);
            divisions.put(id, division);
        }

        public Map  getDivisions() {
            return Collections.unmodifiableMap(divisions);  
        }

        /**
         * Class representing division in survey data
         */
        public final static class Division {

            private Map teams;

            private transient final Integer id;
            private final Employee.SortOrder sortOrderOfDataOrEmployees;

            public Division(Integer id, Employee.SortOrder sortOrderOfDataOrEmployees) {
                this.id = id;
                this.sortOrderOfDataOrEmployees = sortOrderOfDataOrEmployees;
                if (Employee.SortOrder.ORIGINAL == sortOrderOfDataOrEmployees)
                    teams = new LinkedHashMap <>();
                else
                    teams = new TreeMap<>();
            }

            @JsonIgnore
            public Integer getId() {
                return id; 
            }   

            public void addTeam(Integer id, Team team) {
                Objects.requireNonNull(id); Objects.requireNonNull(team);
                teams.put(id, team);
            }
            public Team createTeam(Integer id) {
                return new Team(id, sortOrderOfDataOrEmployees);
            }

            public Map getTeams() {
                return Collections.unmodifiableMap(teams);  
            }       
        }

        /**
         * Class representing team in survey data
         */
        public final static class Team {

            private Map managers;

            private transient final Integer id;
            private final Employee.SortOrder sortOrderOfDataOrEmployees;

            public Team(Integer id, Employee.SortOrder sortOrderOfDataOrEmployees) {
                this.id = id;
                this.sortOrderOfDataOrEmployees = sortOrderOfDataOrEmployees;
                if (Employee.SortOrder.ORIGINAL == sortOrderOfDataOrEmployees)
                    managers = new LinkedHashMap <>();
                else
                    managers = new TreeMap<>();
            }

            @JsonIgnore
            public Integer getId() {
                return id; 
            }

            public void addManager(Integer id, Manager manager) {
                Objects.requireNonNull(id); Objects.requireNonNull(manager);
                managers.put(id, manager);
            }           
            public Manager createManager(Integer id, CSVData.SortDirection sortDirectionOfEmployees) {
                return new Manager(id, sortOrderOfDataOrEmployees, sortDirectionOfEmployees);
            }

            public Map getManagers() {
                return Collections.unmodifiableMap(managers);   
            }           
        }

        /**
         * Class representing manager in survey data
         */
        public final static class Manager {

            private final Employee.SortOrder sortOrderOfDataOrEmployees;
            private final CSVData.SortDirection sortDirectionOfEmployees;

            private transient Map employees;

            private transient final Integer id;

            public Manager(Integer id, Employee.SortOrder sortOrderOfDataOrEmployees, CSVData.SortDirection sortDirectionOfEmployees) {
                this.id = id;
                this.sortOrderOfDataOrEmployees = sortOrderOfDataOrEmployees;
                this.sortDirectionOfEmployees = sortDirectionOfEmployees;
                if (Employee.SortOrder.ORIGINAL == sortOrderOfDataOrEmployees)
                    employees = new LinkedHashMap <>();
                else
                    employees = new TreeMap<>();
            }

            @JsonIgnore
            public Integer getId() {
                return id; 
            }   

            public void addEmployee(Integer id, Employee employee) {
                Objects.requireNonNull(id); Objects.requireNonNull(employee);
                employees.put(id, employee);
            }
            public Employee createEmployee(Integer id, String firstName, String lastName, String birthdate) {
                return new Employee(id, firstName, lastName, birthdate);
            }

            public Map getEmployees() {
                return Collections.unmodifiableMap(employees);  
            }

            @JsonProperty("employees")
            public Map getOrderedEmployees() {

                Map orderedMapOfEmployees;
                if ((Employee.SortOrder.ID == sortOrderOfDataOrEmployees && CSVData.SortDirection.ASCENDING == sortDirectionOfEmployees) || Employee.SortOrder.ORIGINAL == sortOrderOfDataOrEmployees)
                    orderedMapOfEmployees = employees;
                else {
                    Comparator valueComparator = (k1, k2) -> {
                          Employee e1 = employees.get(k1);
                          Employee e2 = employees.get(k2);
                          int compare = 0;
                          if(null != e1 && null != e2) {
                              switch (sortOrderOfDataOrEmployees) {
                                case ID:
                                    compare = Integer.valueOf(e1.id).compareTo(Integer.valueOf(e2.id)); 
                                    break;      
                                case LASTNAME:
                                    compare = e1.lastName.compareTo(e2.lastName);       
                                    break;                          
                                case FIRSTNAME:
                                    compare = e1.firstName.compareTo(e2.firstName);     
                                    break;  
                                case BIRTHDATE:
                                    compare = e1.birthdate.compareTo(e2.birthdate);     
                                    break;
                                default:
                                    assert false;
                                    break;
                              }
                              if (CSVData.SortDirection.DESCENDING == sortDirectionOfEmployees)
                                  compare = -compare;
                          }
                          else
                              throw new NullPointerException("Comparator does not support null values");
                          return compare;
                    };

                    Map sortedMapOfEmployees = new TreeMap<>(valueComparator);
                    sortedMapOfEmployees.putAll(employees);
                    orderedMapOfEmployees = sortedMapOfEmployees;
                }
                return orderedMapOfEmployees;
            }

            @Override                   
            public String toString() {
                return Objects.toString(employees); 
            }
        }

        /**
         * Class representing employee in survey data
         */
        public final static class Employee {

            private final int id;
            private final String firstName;
            private final String lastName;          
            private final String birthdate;

            private transient final LocalDate birthdateDateType;

            public Employee(int id, String firstName, String lastName, String birthdate) {
                this.id = id;
                this.firstName = firstName;
                this.lastName = lastName;
                this.birthdate = birthdate;
                this.birthdateDateType = LocalDate.parse(birthdate, FORMATTER);         // NOTE - Formatter is not thread safe
            }

            public int getId() {
                return id;
            }
            public String getFirstName() {
                return firstName;
            }
            public String getLastName() {
                return lastName;
            }
            public String getBirthdate() {
                return birthdate;
            }
            @JsonIgnore
            public LocalDate getBirthdateDateType() {
                return birthdateDateType;
            }

            @Override                   
            public String toString() {
                return "(id='" + id + "', firstName='" + firstName + "', lastName='" + lastName + "', birthdate='" + birthdate + "')";
            }

            public enum SortOrder {
                ORIGINAL,
                ID,
                LASTNAME,
                FIRSTNAME,
                BIRTHDATE
            }
        }       
    }
}

AgeCalculator.java

package org.challenge.analysis;

import java.time.Period;
import java.util.Optional;

/**
 * Interface for obtaining average age from survey data at different scopes
 *
 */
public interface AgeCalculator {

    /**
     * Calculate average age of employees within a specified scope
     * @param scope enum value
     * @param id of division, team or manager, can be not present for company scope
     * @return Period of time showing the average age
     * @exception  AgeCalculatorException if id is not present for non-company scope
     */
    Period getAverageAge(Scope scope, Optional id) throws AgeCalculatorException;

    public enum Scope {
        COMPANY,
        DIVISION,           
        TEAM,
        MANAGER
    }

    /**
     * Exception class for age calculator
     */
    class AgeCalculatorException extends Exception {
        private static final long serialVersionUID = 1L;

        AgeCalculatorException(String message) {
            super(message);
        }
        AgeCalculatorException(String message, Exception inner) {
            super(message, inner);
        }
    }   
}

SurveyAnalyzer.java

package org.challenge.analysis;

import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.util.Objects;
import java.util.Optional;

import org.challenge.csv.survey.SurveyCSVParser;

/**
 * Class implementing average age calculations on survey data  
 *
 */
public final class SurveyAnalyzer implements AgeCalculator {

    private final SurveyCSVParser.SurveyCSVData surveyData;

    public SurveyAnalyzer(SurveyCSVParser.SurveyCSVData surveyData) {
        this.surveyData = surveyData;
    }

    @Override
    public Period getAverageAge(Scope scope, Optional id) throws AgeCalculator.AgeCalculatorException {

        if (AgeCalculator.Scope.COMPANY != scope && (null == id || false == id.isPresent()))
            throw new AgeCalculator.AgeCalculatorException("For non-COMPANY scope an identifier is required");

        long totalDaysAgeOfEmployeesInScope, totalEmployeesInScope;     
        switch (scope) {

            default:    
            //case COMPANY:
                totalDaysAgeOfEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .mapToLong(e -> Duration.between(e.getBirthdateDateType().atStartOfDay(), LocalDate.now().atStartOfDay()).toDays()).sum();
                totalEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .count();
                break;
            case DIVISION:
                totalDaysAgeOfEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .filter(d -> Objects.equals(d.getId(), id.get()))
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .mapToLong(e -> Duration.between(e.getBirthdateDateType().atStartOfDay(), LocalDate.now().atStartOfDay()).toDays()).sum();
                totalEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .filter(d -> Objects.equals(d.getId(), id.get()))
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .count();
                break;
            case TEAM:
                totalDaysAgeOfEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .filter(t -> Objects.equals(t.getId(), id.get()))
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .mapToLong(e -> Duration.between(e.getBirthdateDateType().atStartOfDay(), LocalDate.now().atStartOfDay()).toDays()).sum();
                totalEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .filter(t -> Objects.equals(t.getId(), id.get()))
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .count();
                break;
            case MANAGER:
                totalDaysAgeOfEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .filter(m -> Objects.equals(m.getId(), id.get()))
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .mapToLong(e -> Duration.between(e.getBirthdateDateType().atStartOfDay(), LocalDate.now().atStartOfDay()).toDays()).sum();
                totalEmployeesInScope = surveyData.getDivisions().values().parallelStream()
                        .flatMap(d -> d.getTeams().values().parallelStream())
                        .flatMap(t -> t.getManagers().values().parallelStream())
                        .filter(m -> Objects.equals(m.getId(), id.get()))
                        .flatMap(m -> m.getEmployees().values().parallelStream())
                        .count();
                break;
        }

        long averageAgeDays = 0;
        if (totalEmployeesInScope > 0)
            averageAgeDays = (long)Math.floor(totalDaysAgeOfEmployeesInScope / totalEmployeesInScope);      // NOTE - Some rounding down here to nearest day over all employees in scope
        Period averageAge = Period.between(LocalDate.now(), LocalDate.now().plusDays(averageAgeDays));
        return averageAge;
    }
}

Task1.java

package org.challenge;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Period;
import java.util.Objects;
import java.util.Optional;

import org.challenge.analysis.AgeCalculator;
import org.challenge.analysis.AgeCalculator.AgeCalculatorException;
import org.challenge.analysis.SurveyAnalyzer;
import org.challenge.csv.CSVData;
import org.challenge.csv.CSVParser;
import org.challenge.csv.Parser;
import org.challenge.csv.survey.SurveyCSVParser;
import org.challenge.json.JSONWriter;


/**
 * Main class with entry point
 *
 */
class Task1 {

    /**
     * Main entry point
     * @param args
     */
    public static void main(String[] args) {

        try {
            // Path to supplied CSV data file
            Path csvFilePath = Paths.get("data", "data.csv");

            // Process command-line arguments for sort order and direction
            org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData.Employee.SortOrder employeeSortOrder = processSortOrder(args);
            org.challenge.csv.CSVData.SortDirection employeeSortDirection = processSortAscendingDescending(args);

            // Create the parser
            Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile(), employeeSortOrder, employeeSortDirection);

            long timeBeforeWorkMs = System.nanoTime();

            // Parse into object structure
            Optional csvDataObjectsOrNull = csvParser.parse();     
            if (true == csvDataObjectsOrNull.isPresent())
            {
                CSVData csvDataObjects = csvDataObjectsOrNull.get();
                Objects.requireNonNull(csvDataObjects, "FAILED to parse CSV");

                // Create the writer
                JSONWriter writerofJson = new JSONWriter(csvDataObjects);

                // Write out objects as JSON
                String jsonStringRepresentation = writerofJson.write();
                Objects.requireNonNull(jsonStringRepresentation, "FAILED to output JSON");

                System.out.println("Processed in " + (System.nanoTime() - timeBeforeWorkMs) + "ms");

                // Dump JSON to console
                System.out.println("JSON formatted survey data");
                System.out.println(jsonStringRepresentation);                           // NOTE - Verify and pretty print JSON output at https://jsonlint.com/

                // Check we have survey data
                if (true == csvDataObjects instanceof SurveyCSVParser.SurveyCSVData) {

                    SurveyCSVParser.SurveyCSVData surveyData = (SurveyCSVParser.SurveyCSVData)csvDataObjects;

                    // Dump some sample object data to console
                    SurveyCSVParser.SurveyCSVData.Manager sampleManager = surveyData.getDivisions().get(1).getTeams().get(5).getManagers().get(1);
                    System.out.println("Division 1, Team 5, Manager 1 has employees: " + sampleManager);

                    try {
                        // Create survey data analyzer
                        AgeCalculator averageAgeCalculator = new SurveyAnalyzer(surveyData);
                        Period averageAge;

                        // Calculate some sample average ages and dump to console
                        averageAge = averageAgeCalculator.getAverageAge(AgeCalculator.Scope.COMPANY, Optional.empty());
                        System.out.println("Average age of employees in company: " + formatPeriod(averageAge));

                        averageAge = averageAgeCalculator.getAverageAge(AgeCalculator.Scope.DIVISION, Optional.of(1));      // NOTE - Samples only, not added to command line arguments
                        System.out.println("Average age of employees in division 1: " + formatPeriod(averageAge));

                        averageAge = averageAgeCalculator.getAverageAge(AgeCalculator.Scope.TEAM, Optional.of(12));
                        System.out.println("Average age of employees in team 12: " + formatPeriod(averageAge));

                        averageAge = averageAgeCalculator.getAverageAge(AgeCalculator.Scope.MANAGER, Optional.of(2));
                        System.out.println("Average age of employees under manager 2: " + formatPeriod(averageAge));
                    }
                    catch (AgeCalculatorException e) {
                        System.out.println("AGE EXCEPTION: " + e.toString());
                    }
                }
                else {
                    System.out.println("UNEXPECTED CSV data type");
                }
            }
            else {
                System.out.println("FAILED to parse CSV data");
            }

            System.out.flush();
        }
        catch (Exception e) {
            System.out.println("EXCEPTION: " + e.toString());
        }
    }

    private static org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData.Employee.SortOrder processSortOrder(String[] args) {

        org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData.Employee.SortOrder sortOrder = org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL;

        if (args.length > 0) {
            try {
                sortOrder = Enum.valueOf(org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData.Employee.SortOrder.class, args[0]);             
            }
            catch (IllegalArgumentException e) {
                System.out.println("FAILED to process sort order, defaulting to ORIGINAL");
            }
        }
        System.out.println("Sort order is " + sortOrder.name());

        return sortOrder;
    }

    private static org.challenge.csv.CSVData.SortDirection processSortAscendingDescending(String[] args) {

        org.challenge.csv.CSVData.SortDirection sortDirection = org.challenge.csv.CSVData.SortDirection.ASCENDING;

        if (args.length > 1) {
            if (true == "DESC".equalsIgnoreCase(args[1]))
                sortDirection = org.challenge.csv.CSVData.SortDirection.DESCENDING;         
        }
        System.out.println("Sort direction is " + sortDirection.name());

        return sortDirection;       
    }

    private static String formatPeriod(Period period) {
        String formattedPeriod = String.format("%d years, %d months, %d days", period.getYears(), period.getMonths(), period.getDays());
        return formattedPeriod;
    }
}

Tests:

CSVParserTests.java

package org.challenge.csv;

import static org.junit.Assert.*;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;

import org.challenge.csv.survey.SurveyCSVParser.SurveyCSVData;

import org.junit.Test;

public class CSVParserTests {

    @Test
    public void testParse_givenCSV_success() {

        Path csvFilePath = Paths.get("data", "data.csv");

        Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile());
        assertNotNull(csvParser);

        Optional csvData = csvParser.parse();  
        assertNotNull(csvData.orElse(null));
        assertTrue(csvData.get() instanceof SurveyCSVData);
        SurveyCSVData surveyData = (SurveyCSVData)csvData.get();
        assertNotNull(surveyData.getDivisions());
        assertNotNull(surveyData.getDivisions().get(1));
    }

    @Test
    public void testParse_emptyCSV_success() {

        Path csvFilePath = Paths.get("data", "empty.csv");

        Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile());
        assertNotNull(csvParser);

        Optional csvData = csvParser.parse();  
        assertNotNull(csvData.orElse(null));
        assertTrue(csvData.get() instanceof SurveyCSVData);
        SurveyCSVData surveyData = (SurveyCSVData)csvData.get();
        assertNotNull(surveyData.getDivisions());
        assertEquals(0, surveyData.getDivisions().size());
    }

    @Test
    public void testParse_extraCSV_success() {

        Path csvFilePath = Paths.get("data", "extra.csv");

        Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile());
        assertNotNull(csvParser);

        Optional csvData = csvParser.parse();  
        assertNotNull(csvData.orElse(null));
        assertTrue(csvData.get() instanceof SurveyCSVData);
        SurveyCSVData surveyData = (SurveyCSVData)csvData.get();
        assertNotNull(surveyData.getDivisions());
        assertNotNull(surveyData.getDivisions().get(1));
    }

    @Test
    public void testParse_badCSV_failure() {

        Path csvFilePath = Paths.get("data", "badformat.csv");

        Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile());
        assertNotNull(csvParser);

        Optional csvData = csvParser.parse();  
        assertNull(csvData.orElse(null));
    }

    @Test
    public void testParse_nonExistantCSV_failure() {

        Path csvFilePath = Paths.get("data", "missing.csv");

        Parser csvParser = CSVParser.createSurveyParser(csvFilePath.toFile());
        assertNotNull(csvParser);

        Optional csvData = csvParser.parse();  
        assertNull(csvData.orElse(null));
    }
}

JSONWriterTests.java

package org.challenge.json;

import static org.junit.Assert.*;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import org.challenge.csv.CSVData;
import org.challenge.csv.survey.SurveyCSVParser;

import org.junit.Test;

import com.fasterxml.jackson.core.JsonProcessingException;

public class JSONWriterTests {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d");

    @Test
    public void testWrite_success() {

        SurveyCSVParser.SurveyCSVData surveyData = buildSampleData();

        JSONWriter writerOfJson = new JSONWriter(surveyData);

        try {
            String jsonString = writerOfJson.write();
            assertNotNull(jsonString);
            assertTrue(jsonString.length() > 0);
        }
        catch (JsonProcessingException e) {
            fail("JSON processing failed");
        }
    }

    private SurveyCSVParser.SurveyCSVData buildSampleData() {

        SurveyCSVParser.SurveyCSVData surveyData = new SurveyCSVParser.SurveyCSVData(SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);

        SurveyCSVParser.SurveyCSVData.Division division = new SurveyCSVParser.SurveyCSVData.Division(1, SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);
        SurveyCSVParser.SurveyCSVData.Team team = division.createTeam(1);
        SurveyCSVParser.SurveyCSVData.Manager manager = team.createManager(1, CSVData.SortDirection.ASCENDING);
        SurveyCSVParser.SurveyCSVData.Employee employee = manager.createEmployee(1, "Stuart", "Mackintosh", LocalDate.now().minusDays(1).format(FORMATTER));

        manager.addEmployee(1, employee);
        team.addManager(1, manager);
        division.addTeam(1, team);
        surveyData.addDivision(1, division);

        return surveyData;
    }
}

SurveyAnalyzerTests.java

package org.challenge.analysis;

import static org.junit.Assert.*;

import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Optional;

import org.challenge.csv.CSVData;
import org.challenge.csv.survey.SurveyCSVParser;

import org.junit.Test;

public class SurveyAnalyzerTests {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d");

    @Test
    public void test_CompanyScope_success() throws AgeCalculator.AgeCalculatorException {

        SurveyCSVParser.SurveyCSVData surveyData = buildSampleData();

        SurveyAnalyzer analysis = new SurveyAnalyzer(surveyData);
        Period period = analysis.getAverageAge(AgeCalculator.Scope.COMPANY, Optional.empty());
        assertNotNull(period);
        assertEquals(1, period.getDays());      
    }

    @Test
    public void test_NoEmployees_success() throws AgeCalculator.AgeCalculatorException {

        SurveyCSVParser.SurveyCSVData surveyData = buildEmptySampleData();

        SurveyAnalyzer analysis = new SurveyAnalyzer(surveyData);
        Period period = analysis.getAverageAge(AgeCalculator.Scope.COMPANY, Optional.empty());
        assertNotNull(period);
        assertTrue(period.equals(Period.ZERO));     
    }

    @Test
    public void test_DivisionScope_success() throws AgeCalculator.AgeCalculatorException {

        SurveyCSVParser.SurveyCSVData surveyData = buildSampleData();

        SurveyAnalyzer analysis = new SurveyAnalyzer(surveyData);
        Period period = analysis.getAverageAge(AgeCalculator.Scope.DIVISION, Optional.of(1));
        assertNotNull(period);
        assertEquals(1, period.getDays());      
    }

    @Test(expected=AgeCalculator.AgeCalculatorException.class)
    public void test_DivisionScope_failure() throws AgeCalculator.AgeCalculatorException {

        SurveyCSVParser.SurveyCSVData surveyData = buildEmptySampleData();

        SurveyAnalyzer analysis = new SurveyAnalyzer(surveyData);
        analysis.getAverageAge(AgeCalculator.Scope.DIVISION, null);     
    }

    private SurveyCSVParser.SurveyCSVData buildSampleData() {

        SurveyCSVParser.SurveyCSVData surveyData = new SurveyCSVParser.SurveyCSVData(SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);

        SurveyCSVParser.SurveyCSVData.Division division = new SurveyCSVParser.SurveyCSVData.Division(1, SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);
        SurveyCSVParser.SurveyCSVData.Team team = division.createTeam(1);
        SurveyCSVParser.SurveyCSVData.Manager manager = team.createManager(1, CSVData.SortDirection.ASCENDING);
        SurveyCSVParser.SurveyCSVData.Employee employee1 = manager.createEmployee(1, "Stuart", "Mackintosh", LocalDate.now().minusDays(1).format(FORMATTER));
        SurveyCSVParser.SurveyCSVData.Employee employee2 = manager.createEmployee(2, "Stuart L", "Mackintosh", LocalDate.now().minusDays(2).format(FORMATTER));

        manager.addEmployee(1, employee1);
        manager.addEmployee(2, employee2);
        team.addManager(1, manager);
        division.addTeam(1, team);
        surveyData.addDivision(1, division);

        return surveyData;
    }

    private SurveyCSVParser.SurveyCSVData buildEmptySampleData() {

        SurveyCSVParser.SurveyCSVData surveyData = new SurveyCSVParser.SurveyCSVData(SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);

        SurveyCSVParser.SurveyCSVData.Division division = new SurveyCSVParser.SurveyCSVData.Division(1, SurveyCSVParser.SurveyCSVData.Employee.SortOrder.ORIGINAL);
        SurveyCSVParser.SurveyCSVData.Team team = division.createTeam(1);
        SurveyCSVParser.SurveyCSVData.Manager manager = team.createManager(1, CSVData.SortDirection.ASCENDING);

        team.addManager(1, manager);
        division.addTeam(1, team);
        surveyData.addDivision(1, division);

        return surveyData;      
    }
}

My instructions/answers:

Eclipse Photon project for Challenge

Requirements:
–Java 8
–Gradle 4.3
–Jackson 2.4
–JUnit 4.12

Build with Gradle:

Gradlew.bat build

Execute main in /src/main/java/org/challenge/Task1.java, possible arguments to control the data sort order and employee sort order are:

[ORIGINAL/ID/LASTNAME/FIRSTNAME/BIRTHDATE] [ASC/DESC]

e.g.

java ... org.challenge.Test1 LASTNAME DESC
java ... org.challenge.Test1 ID
java ... org.challenge.Test1

Run unit tests under /src/test/java/*:

Gradlew.bat test

For Javadoc:

Gradlew.bat javadoc

Questions

  1. Time complexity is linear or O(n) without sorting, i.e. ORIGINAL, each line of the CSV file is processed once, map insertions and gets are O(1) for unsorted hash maps or O(log n) for sorted maps. Space complexity is O(n).
  2. Use ID command-line argument to obtain all data sorted by ID, the argument ORIGINAL (default) will use CSV data order.
  3. Use ID, LASTNAME, FIRSTNAME or BIRTHDATE arguments to set sort order of employees, optionally with ASC or DESC to set sort direction, the default is ascending.
  4. The program will output some calculated average ages for the company and one sample division, team and manager at the end. I didn’t add command-line arguments for this.

Assumptions

Employee birthdate is always in yyyy-M-D format.
The CSV file can be read entirely into available heap.
A badly formatted CSV row will end the parsing operation.
File reading will not be retried.
Integer data type can contain all IDs.
Long data type can contain the total age in days of all employees during the scope of the average age calculation.
Average age of all employees in scope is rounded down to the nearest day.

Converting historic pounds, shillings and pence (£sd) to modern worth?

On other genealogy sites I often see people ask “what would £X be worth today” questions, and I never really have a good answer. Particularly with UK probate records becoming more accessible, it is often straightforward to find out how much a person owned when they died, but less easy to interpret what that sum actually meant. How much was “wealthy”, how much was “poor”…

I know of a few online converters, but they often seem to give inconsistent results.

So, how would you answer the question: What would £100 in 1750 be worth today?

Get back original word doc after converting to pdf

Unfortunately I submitted an assignment at university after converting a word document to a pdf with pandoc word, where I now realize some of my text was hidden since the text box was too small to fit it all.

I lost marks because of this and am now wondering if they can be recuperated by converting it back to a word document that still has that data?

I assume it isn’t possible and, admittedly, I’m a bit ignorant of how the conversion process works. If anyone has any ideas that would be greatly appreciated.

How to allow special characters when converting array from csv php

I would like to ask on how my conversion won’t accept the csv cell that has special characters with ‘ñ’ upon debugging it skip the values with special characters.

you may look at the pictures i attached

picture of the sample csv

picture of the converted in php

for ($i = 0; $i < sizeof($_cb_arr); $i++) {
    $_filename = $_cb_arr[$i];
    $excelObj = PHPExcel_IOFactory::load($_path . $_filename);
    $worksheet = $excelObj->getActiveSheet();
    $excelObjHeaders = PHPExcel_IOFactory::load('config/headers.csv');
    $worksheetHeaders = $excelObjHeaders->getActiveSheet();
    $lastRow = $worksheet->getHighestRow();
    $lastColumn = $worksheet->getHighestColumn();
    $lastColumn++;

    for ($row = 1; $row <= $lastRow; $row++) {
        if ($row == 1 && $header) {
            $cont .= '';
            for ($column = 'A'; $column != $lastColumn; $column++) {

                $cell = trim($worksheet->getCell($column.$row)->getValue());
                utf8_encode($cell);
                $cont .= '' . $cell . ':';
            }
            $header = false;
            $cont .= '';
        } else if ($row != 1) {

            $data[utf8_encode($data_row)] = array();
            $cont .= '
                ';
            for ($column = 'A'; $column != $lastColumn; $column++) {

                $cell = trim($worksheet->getCell($column.$row)->getValue());
                utf8_encode($cell);

                $data[$data_row]["xml"][trim($worksheetHeaders->getCell($column."1")->getValue())] = $cell;
                $cont .= '
                    ' . $cell . '';
            }

            $data[$data_row]["group"] = explode("_", $_filename)[0];
            $ex = explode(".", $_filename)[0];
            $exc = sizeof(explode("_", $ex)) == 5 ? 4 : 3;
            $data[$data_row]["last"] = explode(".", explode("_", $_filename)[$exc])[0];
            $data_row++;
            $cont .= '
                ';

        }
    }
}