Understanding a basic math concept with algebra.

I have the following equation
$C + I + G$
and the second equation
$C+T+S^P$.

Now i know that $C + I + G$ = $C+T+S^P$$S^P+(T-G) = I$

What is this concept called and why is this?
I know this is very basic, but any help is greatly appreciated.

naming – How to name a domain concept when experts use different terms?

The DDD literature is quite clear that when a word/term has a different meaning for different users, a Bounded Context should be created to be able to separate the domain models.

I’m facing the situation where two different terms are being used to describe the same concept and I’m having a hard time figuring out how to handle this situation. Should I hold a popular vote among the domain experts to pick the most widely used term? Should we discuss it further and come up with a third name that would satisfy everyone (not sure it’s possible)? Any other suggestions?

Note that in the UI it wouldn’t be so hard to show the ‘correct’ term to the users. I’m mainly talking about how to call the concept in the model and source code.

Some context:

Organisation has two existing off the shelf applications. Application A calls a concept Foo and application B calls the same concept Bar. Both applications have API’s and I’m creating an integration application that allows users to get and manipulate data from both applications.

Application A is the source, when a new Foo is created, my application will create a new thing. Application B also reacts to the creation of Foo and my application will use data from B as well. Various users will work with the thing, until the process is complete and the thing will dissapear. My application will be used by users who work with Application A or Application B.

JAVA OOP concept issue – Code Review Stack Exchange

Hello guys could you help me please how to render this code as OOP?

I want to improve this code and follow the OOP anyone could help me, please

thank you in advance

this is class Expression

class Expression {
        public int type;
        public int value;
        public Expression leftOp;
        public Expression rightOp;
    
        public Expression(int type, int value, Expression leftOp, Expression rightOp) {
            this.type = type;
            this.value = value;
            this.leftOp = leftOp;
            this.rightOp = rightOp;
        }
    }


    class Arith {
    

/** Constantes pour representer les types */
        public static final int TYPE_NUMBER = 1;
        public static final int TYPE_SUM = 2;
        public static final int TYPE_PROD = 3;

    

    public static void main(String() args) {
     
            Expression term = new Expression(TYPE_SUM, 0, new Expression(TYPE_NUMBER, 3, null, null), new Expression(
                    TYPE_PROD, 0, new Expression(TYPE_NUMBER, 2, null, null), new Expression(TYPE_NUMBER, 5, null, null)));
            System.out.println(evaluate(term));
        }
    
        /** Evalue recursivement the expression */
        public static int evaluate(Expression term) {
            switch (term.type) {
            case TYPE_NUMBER:
                return term.value;
            case TYPE_SUM:
                return evaluate(term.leftOp) + evaluate(term.rightOp);
            case TYPE_PROD:
                return evaluate(term.leftOp) * evaluate(term.rightOp);
            default:
                return 0; 
            }
        }
    }

data structures – some misunderstanding in concept of Huffman algorithm

What is difference between Average length of codes and Average length of codewords in Huffman Algorithm? is both the same meaning? I get stuck in some facts:

I see a fact that marked as False:

for a text that it’s characters get from set of n alphabets then
average length of codes is O(log n).

I ran into a bigger challenge when see these two facts:

The average codeword length in Huffman’s algorithm is Omega(log n).

The average codeword length in Huffman’s algorithm is O(log n).

I need a very small example to clear the difference between these concepts.

Concept not clear: Permuation and Combinations

Q: There are 5 shirts all of different colors, 4 pairs of pants all of different colors, and 2 pairs of shoes with different colors. In how many ways can Amy and Bunny be dressed up with a shirt, a pair of pants, and a pair of shoes each ? ( Question from Brilliant App ).

Solution: (5c2 * 2!) * (4c2 * 2!) * (2c2 * 2!) = 480

My approach:
No of permutations = 5 * 4 * 2 == 40 ways of ordering

Choosing 2 from these 40 orderings = 40c2 * 2! = 1560

Please let me know what is wrong with my approach.

performance – A recursive_transform Template Function Implementation with std::invocable Concept and Execution Policy in C++

This is a follow-up question for A recursive_transform Template Function Implementation with std::invocable concept in C++ and A recursive_transform Template Function with Execution Policy. Based on the previous questions, I am trying to consider execution policy parameter for recursive_transform function here.

The experimental implementation

//  recursive_transform implementation (with execution policy)
template<class ExPo, class T, std::invocable<T> F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr auto recursive_transform(ExPo execution_policy, const T& input, const F& f)
{
    return f(input);
}

//  specific case for std::array
template<class ExPo, class T, std::size_t S, class F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr auto recursive_transform(ExPo execution_policy, const std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(execution_policy, *input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        (execution_policy, &f)(auto&& element)
        {
            return recursive_transform(execution_policy, element, f);
        }
    );
    return output;
}

template<class ExPo, template<class...> class Container, class Function, class... Ts>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (is_inserterable<Container<Ts...>> && !std::invocable<Function, Container<Ts...>>)
constexpr auto recursive_transform(ExPo execution_policy, const Container<Ts...>& input, const Function& f)
{
    using TransformedValueType = decltype(recursive_transform(execution_policy, *input.cbegin(), f));
    Container<TransformedValueType> output(input.size());

    std::transform(execution_policy, input.cbegin(), input.cend(), output.begin(),
        (&)(auto&& element)
        {
            return recursive_transform(execution_policy, element, f);
        }
    );

    return output;
}

#ifdef USE_BOOST_MULTIDIMENSIONAL_ARRAY
template<class ExPo, is_multi_array T, class F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (!std::invocable<F, T>)
constexpr auto recursive_transform(const T& input, const F& f)
{
    boost::multi_array output(input);
    for (decltype(+input.shape()(0)) i = 0; i < input.shape()(0); i++)
    {
        output(i) = recursive_transform(execution_policy, input(i), f);
    }
    return output;
}
#endif

Test cases

//  std::vector<int> -> std::vector<std::string>
std::vector<int> test_vector = {
    1, 2, 3
};
std::cout << "string: " + recursive_transform(std::execution::par, test_vector, ()(int x)->std::string { return std::to_string(x); }).at(0) << std::endl;


//  std::vector<std::vector<int>> -> std::vector<std::vector<std::string>>
std::vector<decltype(test_vector)> test_vector2 = {
    test_vector, test_vector, test_vector
};
std::cout << "string: " + recursive_transform(std::execution::par, test_vector2, ()(int x)->std::string { return std::to_string(x); }).at(0).at(0) << std::endl;

//std::vector<std::vector<int>> -> std::vector<std::size_t>
std::cout << "recursive_count_if: " + recursive_transform(std::execution::par, test_vector2, ()(std::vector<int> x) {
    return std::to_string(recursive_count_if(x, ()(int number) { return number == 3; }));
    }).at(0) << std::endl;

The full testing code:

#include <algorithm>
#include <array>
#include <cassert>
#include <chrono>
#include <complex>
#include <concepts>
#include <deque>
#include <exception>
#include <execution>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <optional>
#include <ranges>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>

template<typename T>
concept is_inserterable = requires(T x)
{
    std::inserter(x, std::ranges::end(x));
};

#ifdef USE_BOOST_MULTIDIMENSIONAL_ARRAY
template<typename T>
concept is_multi_array = requires(T x)
{
    x.num_dimensions();
    x.shape();
    boost::multi_array(x);
};
#endif

//  recursive_count implementation
template<std::ranges::input_range Range, typename T>
constexpr auto recursive_count(const Range& input, const T& target)
{
    return std::count(input.cbegin(), input.cend(), target);
}

//  transform_reduce version
template<std::ranges::input_range Range, typename T>
requires std::ranges::input_range<std::ranges::range_value_t<Range>>
constexpr auto recursive_count(const Range& input, const T& target)
{
    return std::transform_reduce(std::cbegin(input), std::cend(input), std::size_t{}, std::plus<std::size_t>(), (target)(auto&& element) {
        return recursive_count(element, target);
        });
}

//  recursive_count implementation (with execution policy)
template<class ExPo, std::ranges::input_range Range, typename T>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr auto recursive_count(ExPo execution_policy, const Range& input, const T& target)
{
    return std::count(execution_policy, input.cbegin(), input.cend(), target);
}

template<class ExPo, std::ranges::input_range Range, typename T>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (std::ranges::input_range<std::ranges::range_value_t<Range>>)
constexpr auto recursive_count(ExPo execution_policy, const Range& input, const T& target)
{
    return std::transform_reduce(execution_policy, std::cbegin(input), std::cend(input), std::size_t{}, std::plus<std::size_t>(), (execution_policy, target)(auto&& element) {
        return recursive_count(execution_policy, element, target);
        });
}

//  recursive_count_if implementation
template<class T, std::invocable<T> Pred>
constexpr std::size_t recursive_count_if(const T& input, const Pred& predicate)
{
    return predicate(input) ? 1 : 0;
}

template<std::ranges::input_range Range, class Pred>
requires (!std::invocable<Pred, Range>)
constexpr auto recursive_count_if(const Range& input, const Pred& predicate)
{
    return std::transform_reduce(std::cbegin(input), std::cend(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto&& element) {
        return recursive_count_if(element, predicate);
    });
}

//  recursive_count_if implementation (with execution policy)
template<class ExPo, class T, std::invocable<T> Pred>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr std::size_t recursive_count_if(ExPo execution_policy, const T& input, const Pred& predicate)
{
    return predicate(input) ? 1 : 0;
}

template<class ExPo, std::ranges::input_range Range, class Pred>
requires ((std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (!std::invocable<Pred, Range>))
constexpr auto recursive_count_if(ExPo execution_policy, const Range& input, const Pred& predicate)
{
    return std::transform_reduce(execution_policy, std::cbegin(input), std::cend(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto&& element) {
        return recursive_count_if(element, predicate);
    });
}

//  recursive_transform implementation
template<class T, std::invocable<T> F>
constexpr auto recursive_transform(const T& input, const F& f)
{
    return f(input);
}

//  specific case for std::array
template<class T, std::size_t S, class F>
constexpr auto recursive_transform(const std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        (&f)(auto&& element)
        {
            return recursive_transform(element, f);
        }
    );
    return output;
}

template<template<class...> class Container, class Function, class... Ts>
requires (is_inserterable<Container<Ts...>> && !std::invocable<Function, Container<Ts...>>)
constexpr auto recursive_transform(const Container<Ts...>& input, const Function& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));
    Container<TransformedValueType> output;

    std::transform(input.cbegin(), input.cend(), std::inserter(output, std::ranges::end(output)),
        (&)(auto&& element)
        {
            return recursive_transform(element, f);
        }
    );

    return output;
}

#ifdef USE_BOOST_MULTIDIMENSIONAL_ARRAY
template<is_multi_array T, class F>
requires(!std::invocable<F, T>)
constexpr auto recursive_transform(const T& input, const F& f)
{
    boost::multi_array output(input);
    for (decltype(+input.shape()(0)) i = 0; i < input.shape()(0); i++)
    {
        output(i) = recursive_transform(input(i), f);
    }
    return output;
}
#endif

//  recursive_transform implementation (with execution policy)
template<class ExPo, class T, std::invocable<T> F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr auto recursive_transform(ExPo execution_policy, const T& input, const F& f)
{
    return f(input);
}

//  specific case for std::array
template<class ExPo, class T, std::size_t S, class F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>)
constexpr auto recursive_transform(ExPo execution_policy, const std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(execution_policy, *input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        (execution_policy, &f)(auto&& element)
        {
            return recursive_transform(execution_policy, element, f);
        }
    );
    return output;
}

template<class ExPo, template<class...> class Container, class Function, class... Ts>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (is_inserterable<Container<Ts...>> && !std::invocable<Function, Container<Ts...>>)
constexpr auto recursive_transform(ExPo execution_policy, const Container<Ts...>& input, const Function& f)
{
    using TransformedValueType = decltype(recursive_transform(execution_policy, *input.cbegin(), f));
    Container<TransformedValueType> output(input.size());

    std::transform(execution_policy, input.cbegin(), input.cend(), output.begin(),
        (&)(auto&& element)
        {
            return recursive_transform(execution_policy, element, f);
        }
    );

    return output;
}

#ifdef USE_BOOST_MULTIDIMENSIONAL_ARRAY
template<class ExPo, is_multi_array T, class F>
requires (std::is_execution_policy_v<std::remove_cvref_t<ExPo>>) && (!std::invocable<F, T>)
constexpr auto recursive_transform(const T& input, const F& f)
{
    boost::multi_array output(input);
    for (decltype(+input.shape()(0)) i = 0; i < input.shape()(0); i++)
    {
        output(i) = recursive_transform(execution_policy, input(i), f);
    }
    return output;
}
#endif

template<std::size_t dim, class T>
constexpr auto n_dim_vector_generator(T input, std::size_t times)
{
    if constexpr (dim == 0)
    {
        return input;
    }
    else
    {
        auto element = n_dim_vector_generator<dim - 1>(input, times);
        std::vector<decltype(element)> output(times, element);
        return output;
    }
}

template<std::size_t dim, std::size_t times, class T>
constexpr auto n_dim_array_generator(T input)
{
    if constexpr (dim == 0)
    {
        return input;
    }
    else
    {
        auto element = n_dim_array_generator<dim - 1, times>(input);
        std::array<decltype(element), times> output;
        std::fill(std::begin(output), std::end(output), element);
        return output;
    }
}

template<std::size_t dim, class T>
constexpr auto n_dim_deque_generator(T input, std::size_t times)
{
    if constexpr (dim == 0)
    {
        return input;
    }
    else
    {
        auto element = n_dim_deque_generator<dim - 1>(input, times);
        std::deque<decltype(element)> output(times, element);
        return output;
    }
}

template<std::size_t dim, class T>
constexpr auto n_dim_list_generator(T input, std::size_t times)
{
    if constexpr (dim == 0)
    {
        return input;
    }
    else
    {
        auto element = n_dim_list_generator<dim - 1>(input, times);
        std::list<decltype(element)> output(times, element);
        return output;
    }
}

template<std::size_t dim, template<class...> class Container = std::vector, class T>
constexpr auto n_dim_container_generator(T input, std::size_t times)
{
    if constexpr (dim == 0)
    {
        return input;
    }
    else
    {
        return Container(times, n_dim_container_generator<dim - 1, Container, T>(input, times));
    }
}

int main()
{
    //  std::vector<int> -> std::vector<std::string>
    std::vector<int> test_vector = {
        1, 2, 3
    };
    std::cout << "string: " + recursive_transform(std::execution::par, test_vector, ()(int x)->std::string { return std::to_string(x); }).at(0) << std::endl;


    //  std::vector<std::vector<int>> -> std::vector<std::vector<std::string>>
    std::vector<decltype(test_vector)> test_vector2 = {
        test_vector, test_vector, test_vector
    };
    std::cout << "string: " + recursive_transform(std::execution::par, test_vector2, ()(int x)->std::string { return std::to_string(x); }).at(0).at(0) << std::endl;

    //std::vector<std::vector<int>> -> std::vector<std::size_t>
    std::cout << "recursive_count_if: " + recursive_transform(std::execution::par, test_vector2, ()(std::vector<int> x) {
        return std::to_string(recursive_count_if(x, ()(int number) { return number == 3; }));
        }).at(0) << std::endl;

    //  std::deque<int> -> std::deque<std::string>
    std::deque<int> test_deque;
    test_deque.push_back(1);
    test_deque.push_back(1);
    test_deque.push_back(1);

    auto recursive_transform_result3 = recursive_transform(
        std::execution::par,
        test_deque,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result3.at(0) << std::endl;


    //  std::deque<std::deque<int>> -> std::deque<std::deque<std::string>>
    std::deque<decltype(test_deque)> test_deque2;
    test_deque2.push_back(test_deque);
    test_deque2.push_back(test_deque);
    test_deque2.push_back(test_deque);

    auto recursive_transform_result4 = recursive_transform(
        std::execution::par,
        test_deque2,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result4.at(0).at(0) << std::endl;


    //  std::array<int, 10> -> std::array<std::string, 10>
    std::array<int, 10> test_array;
    for (int i = 0; i < 10; i++)
    {
        test_array(i) = 1;
    }
    auto recursive_transform_result5 = recursive_transform(
        std::execution::par,
        test_array,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result5.at(0) << std::endl;

    //  std::array<std::array<int, 10>, 10> -> std::array<std::array<std::string, 10>, 10>
    std::array<std::array<int, 10>, 10> test_array2;
    for (int i = 0; i < 10; i++)
    {
        test_array2(i) = test_array;
    }
    auto recursive_transform_result6 = recursive_transform(
        std::execution::par,
        test_array2,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result6.at(0).at(0) << std::endl;


    //  std::list<int> -> std::list<std::string>
    std::list<int> test_list = { 1, 2, 3, 4 };
    auto recursive_transform_result7 = recursive_transform(
        std::execution::par,
        test_list,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result7.front() << std::endl;


    //  std::list<std::list<int>> -> std::list<std::list<std::string>>
    std::list<std::list<int>> test_list2 = { test_list, test_list, test_list, test_list };
    auto recursive_transform_result8 = recursive_transform(
        std::execution::par,
        test_list2,
        ()(int x)->std::string { return std::to_string(x); });                          //  For testing
    std::cout << "string: " + recursive_transform_result8.front().front() << std::endl;

    return 0;
}

A Godbolt link is here.

All suggestions are welcome.

The summary information:

recursion – A recursive_transform Template Function Implementation with std::invocable concept in C++

This is a follow-up question for A recursive_transform for std::vector with various return type, A recursive_transform Template Function with Execution Policy, A recursive_count_if Template Function with Execution Policy in C++, Avoiding requires clause if possible on a series recursive function in C++ and A recursive_count_if Function with Automatic Type Deducing from Lambda for Various Type Arbitrary Nested Iterable Implementation in C++. The standard concept std::invocable is mentioned in the previous G. Sliepen’s answer and I am trying to use std::invocable concept in recursive_transform template function. In this way, the termination condition can be determined with the input lambda function. Maybe recursive_transform is more generic here.

The experimental implementation

//  recursive_transform implementation
template<class T, std::invocable<T> F>
constexpr auto recursive_transform(const T& input, const F& f)
{
    return f(input);
}

//  specific case for std::array
template<class T, std::size_t S, class F>
constexpr auto recursive_transform(const std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        (f)(auto&& element)
        {
            return recursive_transform(element, f);
        }
    );
    return output;
}

template<template<class...> class Container, class Function, class... Ts>
requires (is_inserterable<Container<Ts...>> && !std::invocable<Function, Container<Ts...>>)
constexpr auto recursive_transform(const Container<Ts...>& input, const Function& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));
    Container<TransformedValueType> output;

    std::transform(input.cbegin(), input.cend(), std::inserter(output, std::ranges::end(output)),
        (&)(auto&& element)
        {
            return recursive_transform(element, f);
        }
    );

    return output;
}

#ifdef USE_BOOST_MULTIDIMENSIONAL_ARRAY
template<is_multi_array T, class F>
requires(!std::invocable<F, T>)
constexpr auto recursive_transform(const T& input, const F& f)
{
    boost::multi_array output(input);
    for (decltype(+input.shape()(0)) i = 0; i < input.shape()(0); i++)
    {
        output(i) = recursive_transform(input(i), f);
    }
    return output;
}
#endif

Test cases

Because of the usage of std::invocable, the termination condition is more flexible instead of simply the base type of nested ranges. In other words, we can play this version of recursive_transform function with recursive_count_if function like this:

//  std::vector<int> -> std::vector<std::string>
std::vector<int> test_vector = {
    1, 2, 3
};
std::cout << "string: " + recursive_transform(test_vector, ()(int x)->std::string { return std::to_string(x); }).at(0) << std::endl;


//  std::vector<std::vector<int>> -> std::vector<std::vector<std::string>>
std::vector<decltype(test_vector)> test_vector2 = {
    test_vector, test_vector, test_vector
};
std::cout << "string: " + recursive_transform(test_vector2, ()(int x)->std::string { return std::to_string(x); }).at(0).at(0) << std::endl;

//std::vector<std::vector<int>> -> std::vector<std::size_t>
std::cout << "recursive_count_if: " + recursive_transform(test_vector2, ()(std::vector<int> x) {
    return std::to_string(recursive_count_if(x, ()(int number) { return number == 3; }));
    }).at(0) << std::endl;

A Godbolt link is here.

All suggestions are welcome.

The summary information:

domain driven design – Can modeling Firestore using CQRS concept will prevent from Firebase locked-in?

Command Query Responsibility Segregation (CQRS) is a pattern that allows to differentiate read and write models.

Both models can work on a single database, or you store a write model in a separate database and use another mechanism to create views for the read model.

The CQRS pattern itself does nothing to prevent vendor lock-in. As with any software system, in order to minimize the dependency on a specific technology, you need to create an abstraction that allows you to swap the underlying implementation without effecting the rest of the application.

This is usually done by creating an additional layer between the two responsibilities. If we look at the database, a common way is to create repository classes that handle communication with the database. The application only knows the repository classes, so if you decide to use a different database technology, only the repository classes need to change.

programming practices – What does Crash Early concept mean?

Exceptions are meant to communicate to your caller that you couldn’t fulfill your job. (That’s the most-ignored fact about exceptions.)

Fail Early

That’s good advice. As soon as you find out that you can’t complete successfully, it’s best to immediately inform your caller about that fact (after cleaning up any inconsistent state that you’d otherwise left behind, it that applies to your application).

Continuing in your program is typically useless, can even be dangerous because of missing or wrong data.

So, e.g. when opening a file, don’t immediately catch the exception, log it and continue. The following code will try to read from that file and of course fail as well.

Generally, you write program statements because your logic needs them. So, if one of your steps fails, the whole method won’t give the desired results. So, let exceptions that you receive simply bubble up the stack, and actively throw appropriate exceptions whenever you detect failure conditions.

Avoid Catching

Although a good general guideline, “Avoid Catching” is over-simplified.

Better: think three times if you really want to catch exceptions here in this place. I’ve seen lots and lots of code cluttered with try/catch constructs that are unnecessary and most of the time even quality traps or plain programming mistakes.

Catch exceptions only in places where you can successfully continue, even after some of your program so far has failed. That translates to the question: Do I have a fallback or recovery strategy available that can turn the failure I just experienced into a success? Maybe by a retry/reconnect or by having an alternative algorithm or whatever.

In catching exceptions, you have to be honest to yourself:

  • You know that something in your current code block failed.
  • You also know how the failing code labeled the type of failure (by means of creating its exception object), or how some layer in-between re-labeled the original failure reason (by wrapping the original exception object). (You see, this isn’t the most reliable source of information.)
  • Take into account that a given exception type might come from any enclosed piece of code, from any level deep down the stack. So don’t assume you know what happened from just looking at the exception object.
  • Having only these informations, can you turn your current method into success?

An honest answer to this reasoning will be “No” in most cases. And then don’t catch the exception.

Valid “Yes” situations are e.g. having a retry/reconnect strategy at hand, or an alternative algorithm, or just reasoning about optional code, something like a cleanup that’s nice to have, but not necessary for making your current method succeed.

You should finally catch exceptions at some top-level (user-interface action level, service API top layer, etc.). There:

  • log the error,
  • tell the user or your client that their request failed,
  • and wait for the next request, that probably (hopefully?) won’t run into the same problem.

Supervisor

What the author calls a supervisor translates to a well-designed catch block in more traditional languages: a place where you know how to deal with a failure in such a way that you can meaningfully continue.

equation solving – concept of tangent and residual in AceFem and automation

Tangent shows the s$$ and residual shows p$$ in the code below.
There are two parts comes under p$$ and s$$ which are connected through p$$, “AddIn” -> True and s$$, "AddIn" -> True respectively.
Here I could not able to understand that what does this ” “AddIn” -> True ” does to the p$$ and s$$? Does it shows the direct addition of first part and second part of p$$?

  1. How exactly SMSStandardModule(“Tangent and residual”) works in acefem. I have already checked with acefem help in mathematica. It seems to me that it operates upon default standard user subroutine for tangent and residual. If yes then I would like to see that how does the subroutine looks and works.
    I also checked the default acefem codes for solving the pde with finite element method.
    There, by directly using SMSStandardModule(“Tangent and residual”) will gives the solution. But in the case below I need to provide each entry of p$$ and s$$ manually. So is there any way to create p$$ and s$$ automatically?
    One of the ways is automatic differentiation. But need more details on that concept.
    Your suggestion’s to make it automaticlly would be helpful to understand the concept.
    Thank you.

SMSStandardModule(“Tangent and residual”);
IOData();

 SMSDo(Ig, 1, SMSIO("No. integration points"));
 {(Xi), (Eta), (Zeta)} (DoubleRightTee) 
   SMSIO("Integration point", Ig);
 wgp (DoubleRightTee) SMSIO("Integration weight", Ig);
 discretization();

 RHS (DoubleRightTee) -{0, (Phi)dot*Ni((1)) - (Omega) (Phi)*
        Nid((1)) - 
       ff*Ni((1)), (Phi)dot*Ni((2)) - (Omega) (Phi)*Nid((2)) - 
       ff*Ni((2))} Jm wgp;
 SMSExport(RHS , p$$, "AddIn" -> True);
    Kt (DoubleRightTee) {{0, 0, 
         0}, {0, -((Ni((1))*Ni((1)))/(CapitalDelta)t) + (Omega) Ni((1))*
           Nid((1)), -((
           Ni((1))*Ni((2)))/(CapitalDelta)t) + (Omega) Ni((2))*
           Nid((1))}, {0, -((
           Ni((2))*Ni((1)))/(CapitalDelta)t) + (Omega) Ni((1))*
           Nid((2)), -((
           Ni((2))*Ni((2)))/(CapitalDelta)t) + (Omega) Ni((2))*
           Nid((2))}} Jm wgp;
    SMSExport(Kt , s$$, "AddIn" -> True);
 SMSEndDo();

 ft (DoubleRightTee) -(Omega) {0, -fluxI((1)), fluxI((2))} ;
 SMSExport(ft , p$$, "AddIn" -> True);
    Ct (DoubleRightTee) (Omega) {{0, 0, 0}, {1, 0, 0}, {0, 0, -1}} ;
    SMSExport(Ct , s$$, "AddIn" -> True);