python – Why do I have an ‘int’ object is not iterable error?

I’m practicing my coding skills and trying to solve a Path with Maximum Gold problem from LeetCode. My current code is below

from typing import List

class Solution:
     def getMaximumGold(self, grid: List(List(int))) -> int:
          total_gold = 0
          m = len(grid)
          n = len(grid(0))
          for i in range(m):
               for j in range(n):
                    if grid(i)(j) != 0:
                         visited = ()
                         path_from_cell = self.searchForPath(m, n, i, j, grid, visited)
                         total_gold = max(total_gold, path_from_cell)
          return total_gold

     def searchForPath(self, m, n, i, j: int, grid: List(List(int)), visited) -> int:
          if grid(i)(j) == 0 or (i,j) in visited or i<0 or j<0 or i>=m or j>=n:
               return 0
          else:
               visited.append((i,j))
               left = self.searchForPath(m, n, i, j-1, grid, visited)
               right = self.searchForPath(m, n, i, j+1, grid, visited)
               up = self.searchForPath(m, n, i-1, j, grid, visited)
               down = self.searchForPath(m, n, i+1, j, grid, visited)
               visited.remove((i,j))
               return max(left,max(right,max(up,max(down)))) + grid(i)(j)

print(Solution().getMaximumGold(grid = ((0,6,0),(5,8,7),(0,9,0))))

It throws the following error:

Traceback (most recent call last):
  File "/home/hasek/Documents/Programming/leetcode.py", line 28, in <module>
    print(Solution().getMaximumGold(grid = ((0,6,0),(5,8,7),(0,9,0))))
  File "/home/hasek/Documents/Programming/leetcode.py", line 12, in getMaximumGold
    path_from_cell = self.searchForPath(m, n, i, j, grid, visited)
  File "/home/hasek/Documents/Programming/leetcode.py", line 24, in searchForPath
    down = self.searchForPath(m, n, i+1, j, grid, visited)
  File "/home/hasek/Documents/Programming/leetcode.py", line 21, in searchForPath
    left = self.searchForPath(m, n, i, j-1, grid, visited)
  File "/home/hasek/Documents/Programming/leetcode.py", line 26, in searchForPath
    return max(left,max(right,max(up,max(down)))) + grid(i)(j)
TypeError: 'int' object is not iterable

I can’t see what’s wrong. Any help will be appreciated.

recursion – A recursive_count Function with Unwrap Level for Various Type Arbitrary Nested Iterable Implementation in C++

This is a follow-up question for A recursive_count Function For Various Type Arbitrary Nested Iterable Implementation in C++, A recursive_count_if Function with Unwrap Level for Various Type Arbitrary Nested Iterable Implementation in C++ and A Function Applier for Applying Various Algorithms on Nested Container Things in C++. I am trying to use unwrap level template parameter as the termination condition of the recursion process in recursive_count template function.

The experimental implementation

The experimental implementation of recursive_count function is as below.

//  recursive_count implementation (the version with unwrap_level)
template<std::size_t unwrap_level, class T, typename ValueType>
constexpr auto recursive_count(const T& input, const ValueType& target)
{
    if constexpr (unwrap_level > 0)
    {
        return std::transform_reduce(std::ranges::cbegin(input), std::ranges::cend(input), std::size_t{}, std::plus<std::size_t>(), (&target)(auto&& element) {
            return recursive_count<unwrap_level - 1>(element, target);
            });
    }
    else
    {
        if (input == target)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

Test cases

The std::vector<int>, std::vector<std::vector<int>>, std::vector<std::string>, std::vector<std::vector<std::string>>, std::deque<int>, std::deque<std::deque<int>>, std::list<int> and std::list<std::list<int>> type input test case has been listed as below.

std::vector<int> test_vector{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };
std::cout << recursive_count<1>(test_vector, 5) << std::endl;

//  std::vector<std::vector<int>>
std::vector<decltype(test_vector)> test_vector2{ test_vector , test_vector , test_vector };
std::cout << recursive_count<2>(test_vector2, 5) << std::endl;

//  std::vector<std::string>
std::vector<std::string> test_string_vector{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
std::cout << recursive_count<1>(test_string_vector, "0") << std::endl;

//  std::vector<std::vector<std::string>>
std::vector<decltype(test_string_vector)> test_string_vector2{ test_string_vector , test_string_vector , test_string_vector };
std::cout << recursive_count<2>(test_string_vector2, "0") << std::endl;

//  std::deque<int>
std::deque<int> test_deque;
test_deque.push_back(1);
test_deque.push_back(2);
test_deque.push_back(3);
test_deque.push_back(4);
test_deque.push_back(5);
test_deque.push_back(6);
std::cout << recursive_count<1>(test_deque, 1) << std::endl;

//  std::deque<std::deque<int>>
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);
std::cout << recursive_count<2>(test_deque2, 1) << std::endl;

//  std::list<int>
std::list<int> test_list = { 1, 2, 3, 4, 5, 6 };
std::cout << recursive_count<1>(test_list, 1) << std::endl;


//  std::list<std::list<int>>
std::list<std::list<int>> test_list2 = { test_list, test_list, test_list, test_list };
std::cout << recursive_count<2>(test_list2, 1) << std::endl;

std::cout << recursive_count<11>(
        n_dim_container_generator<10, std::list>(test_list, 3),
        1
        ) << std::endl;

Full Testing Code

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_copy_if function 
template <std::ranges::input_range Range, std::invocable<std::ranges::range_value_t<Range>> UnaryPredicate>
constexpr auto recursive_copy_if(const Range& input, const UnaryPredicate& unary_predicate)
{
    Range output{};
    std::ranges::copy_if(std::ranges::cbegin(input), std::ranges::cend(input),
        std::inserter(output, std::ranges::end(output)),
        unary_predicate);
    return output;
}

template <
    std::ranges::input_range Range,
    class UnaryPredicate>
constexpr auto recursive_copy_if(const Range& input, const UnaryPredicate& unary_predicate)
{
    Range output{};
    
    std::ranges::transform(
        std::ranges::cbegin(input),
        std::ranges::cend(input),
        std::inserter(output, std::ranges::end(output)),
        (&unary_predicate)(auto&& element) { return recursive_copy_if(element, unary_predicate); }
        );
    return output;
}

//  recursive_count implementation
template<std::ranges::input_range Range, typename T>
constexpr auto recursive_count(const Range& input, const T& target)
{
    return std::count(std::ranges::cbegin(input), std::ranges::cend(input), 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::ranges::cbegin(input), std::ranges::cend(input), std::size_t{}, std::plus<std::size_t>(), (target)(auto&& element) {
        return recursive_count(element, target);
        });
}

//  recursive_count implementation (the version with unwrap_level)
template<std::size_t unwrap_level, class T, typename ValueType>
constexpr auto recursive_count(const T& input, const ValueType& target)
{
    if constexpr (unwrap_level > 0)
    {
        return std::transform_reduce(std::ranges::cbegin(input), std::ranges::cend(input), std::size_t{}, std::plus<std::size_t>(), (&target)(auto&& element) {
            return recursive_count<unwrap_level - 1>(element, target);
            });
    }
    else
    {
        if (input == target)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

//  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, std::ranges::cbegin(input), std::ranges::cend(input), 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::ranges::cbegin(input), std::ranges::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::ranges::cbegin(input), std::ranges::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::ranges::cbegin(input), std::ranges::cend(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto&& element) {
        return recursive_count_if(element, predicate);
    });
}

//  recursive_count_if implementation (the version with unwrap_level)
template<std::size_t unwrap_level, std::ranges::range T, class Pred>
auto recursive_count_if(const T& input, const Pred& predicate)
{
    if constexpr (unwrap_level > 1)
    {
        return std::transform_reduce(std::ranges::cbegin(input), std::ranges::cend(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto&& element) {
            return recursive_count_if<unwrap_level - 1>(element, predicate);
            });
    }
    else
    {
        return std::count_if(std::ranges::cbegin(input), std::ranges::cend(input), predicate);
    }
}

//  recursive_function_applier implementation
template<std::size_t unwrap_level, class F, std::ranges::range Range, class... Args>
constexpr auto recursive_function_applier(const F& function, const Range& input, Args... args)
{
    if constexpr (unwrap_level >= 1)
    {
        Range output{};
        std::ranges::transform(
            std::ranges::cbegin(input),
            std::ranges::cend(input),
            std::inserter(output, std::ranges::end(output)),
            (&function, &args...)(auto&& element) { return recursive_function_applier<unwrap_level - 1>(function, element, args...); }
        );
        return output;
    }
    else
    {
        Range output{};
        function(
            std::ranges::cbegin(input),
            std::ranges::cend(input),
            std::inserter(output, std::ranges::end(output)),
            args...);
        return output;
    }
}

//  recursive_print implementation
template<std::ranges::input_range Range>
constexpr auto recursive_print(const Range& input, const int level = 0)
{
    auto output = input;
    std::cout << std::string(level, ' ') << "Level " << level << ":" << std::endl;
    std::ranges::transform(std::ranges::cbegin(input), std::ranges::cend(input), std::ranges::begin(output),
        (level)(auto&& x)
        {
            std::cout << std::string(level, ' ') << x << std::endl;
            return x;
        }
    );
    return output;
}

template<std::ranges::input_range Range> requires (std::ranges::input_range<std::ranges::range_value_t<Range>>)
constexpr auto recursive_print(const Range& input, const int level = 0)
{
    auto output = input;
    std::cout << std::string(level, ' ') << "Level " << level << ":" << std::endl;
    std::ranges::transform(std::ranges::cbegin(input), std::ranges::cend(input), std::ranges::begin(output),
        (level)(auto&& element)
        {
            return recursive_print(element, level + 1);
        }
    );
    return output;
}

//  recursive_replace_copy_if implementation
template<std::ranges::range Range, std::invocable<std::ranges::range_value_t<Range>> UnaryPredicate, class T>
constexpr auto recursive_replace_copy_if(const Range& input, const UnaryPredicate& unary_predicate, const T& new_value)
{
    Range output{};
    std::ranges::replace_copy_if(
        std::ranges::cbegin(input),
        std::ranges::cend(input),
        std::inserter(output, std::ranges::end(output)),
        unary_predicate,
        new_value);
    return output;
}

template<std::ranges::input_range Range, class UnaryPredicate, class T>
requires (!std::invocable<UnaryPredicate, std::ranges::range_value_t<Range>>)
constexpr auto recursive_replace_copy_if(const Range& input, const UnaryPredicate& unary_predicate, const T& new_value)
{
    Range output{};

    std::ranges::transform(
        std::ranges::cbegin(input),
        std::ranges::cend(input),
        std::inserter(output, std::ranges::end(output)),
        (&unary_predicate, &new_value)(auto&& element) { return recursive_replace_copy_if(element, unary_predicate, new_value); }
    );
    return output;
}

//  recursive_size implementation
template<class T> requires (!std::ranges::range<T>)
constexpr auto recursive_size(const T& input)
{
    return 1;
}

template<std::ranges::range Range> requires (!(std::ranges::input_range<std::ranges::range_value_t<Range>>))
constexpr auto recursive_size(const Range& input)
{
    return std::ranges::size(input);
}

template<std::ranges::range Range> requires (std::ranges::input_range<std::ranges::range_value_t<Range>>)
constexpr auto recursive_size(const Range& input)
{
    return std::transform_reduce(std::ranges::begin(input), std::end(input), std::size_t{}, std::plus<std::size_t>(), ()(auto& element) {
        return recursive_size(element);
        });
}

//  recursive_transform implementation
//  recursive_invoke_result_t implementation
//  from https://stackoverflow.com/a/65504127/6667035
template<typename, typename>
struct recursive_invoke_result { };

template<typename T, std::invocable<T> F>
struct recursive_invoke_result<F, T> { using type = std::invoke_result_t<F, T>; };

template<typename F, template<typename...> typename Container, typename... Ts>
requires (
    !std::invocable<F, Container<Ts...>> &&
    std::ranges::input_range<Container<Ts...>> &&
    requires { typename recursive_invoke_result<F, std::ranges::range_value_t<Container<Ts...>>>::type; })
struct recursive_invoke_result<F, Container<Ts...>>
{
    using type = Container<typename recursive_invoke_result<F, std::ranges::range_value_t<Container<Ts...>>>::type>;
};

template<typename F, typename T>
using recursive_invoke_result_t = typename recursive_invoke_result<F, T>::type;

template <std::ranges::range Range>
constexpr auto get_output_iterator(Range& output)
{
    return std::inserter(output, std::ranges::end(output));
}

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

template <
    std::ranges::input_range Range,
    class F>
requires (!std::invocable<F, Range>)
constexpr auto recursive_transform(const Range& input, const F& f)
{
    recursive_invoke_result_t<F, Range> output{};
    
    std::ranges::transform(
        std::ranges::cbegin(input),
        std::ranges::cend(input),
        std::inserter(output, std::ranges::end(output)),
        (&f)(auto&& element) { return recursive_transform(element, f); }
        );
    return output;
}

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> test_vector{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };
    std::cout << recursive_count<1>(test_vector, 5) << std::endl;

    //  std::vector<std::vector<int>>
    std::vector<decltype(test_vector)> test_vector2{ test_vector , test_vector , test_vector };
    std::cout << recursive_count<2>(test_vector2, 5) << std::endl;

    //  std::vector<std::string>
    std::vector<std::string> test_string_vector{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" };
    std::cout << recursive_count<1>(test_string_vector, "0") << std::endl;

    //  std::vector<std::vector<std::string>>
    std::vector<decltype(test_string_vector)> test_string_vector2{ test_string_vector , test_string_vector , test_string_vector };
    std::cout << recursive_count<2>(test_string_vector2, "0") << std::endl;

    //  std::deque<int>
    std::deque<int> test_deque;
    test_deque.push_back(1);
    test_deque.push_back(2);
    test_deque.push_back(3);
    test_deque.push_back(4);
    test_deque.push_back(5);
    test_deque.push_back(6);
    std::cout << recursive_count<1>(test_deque, 1) << std::endl;

    //  std::deque<std::deque<int>>
    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);
    std::cout << recursive_count<2>(test_deque2, 1) << std::endl;

    //  std::list<int>
    std::list<int> test_list = { 1, 2, 3, 4, 5, 6 };
    std::cout << recursive_count<1>(test_list, 1) << std::endl;


    //  std::list<std::list<int>>
    std::list<std::list<int>> test_list2 = { test_list, test_list, test_list, test_list };
    std::cout << recursive_count<2>(test_list2, 1) << std::endl;

    std::cout << recursive_count<11>(
            n_dim_container_generator<10, std::list>(test_list, 3),
            1
            ) << std::endl;
    return 0;
}

A Godbolt link is here.

All suggestions are welcome.

The summary information:

java – Convert a callback based flow to async iterable

Let’s say I have some event-based flow, for example a “read only” websocket. Normally you set the “onmessage” callback to deal with incoming messages.
Is there some way to access the messages in an async iterator? My goal is to have

async () => {
    for await (const message of SOMETHING(new WebSocket('...'))) {
        // message is the content of the callback
    }
};

I have toyed with promises and queues, but I couldn’t find a way to convert a callback (called multiple times) to an (async-) iterator

recursion – An arithmetic_mean Function For Various Type Arbitrary Nested Iterable Implementation in C++

This is a follow-up question for A recursive_count Function For Various Type Arbitrary Nested Iterable Implementation in C++ and A Summation Function For Boost.MultiArray in C++. I am trying to implement an arithmetic_mean template function for calculating the arithmetic mean value of various type arbitrary nested iterable things. The recursive_reduce function (thanks to G. Sliepen’s answer) and the recursive_size function are used here. Because both recursive_reduce function and recursive_size function are needed in the arithmetic_mean function here, there are two new concepts is_recursive_reduceable and is_recursive_sizeable created as follows.

template<typename T>
concept is_recursive_reduceable = requires(T x)
{
    recursive_reduce(x, 0.0);
};

template<typename T>
concept is_recursive_sizeable = requires(T x)
{
    recursive_size(x);
};

Next, the main part of arithmetic_mean template function:

template<class T> requires (is_recursive_reduceable<T> && is_recursive_sizeable<T>)
auto arithmetic_mean(const T& input)
{
    return (recursive_reduce(input, 0.0)) / (recursive_size(input));
}

Some test cases of this arithmetic_mean template function.

//  std::vector<int> case
std::vector<int> test_vector = {
    1, 2, 3
};
auto arithmetic_mean_result1 = arithmetic_mean(test_vector);
std::cout << arithmetic_mean_result1 << std::endl;

//  std::vector<std::vector<int>> case
std::vector<decltype(test_vector)> test_vector2 = {
    test_vector, test_vector, test_vector
};
auto arithmetic_mean_result2 = arithmetic_mean(test_vector2);
std::cout << arithmetic_mean_result2 << std::endl;

// std::deque<int> case
std::deque<int> test_deque;
test_deque.push_back(1);
test_deque.push_back(1);
test_deque.push_back(1);
auto arithmetic_mean_result3 = arithmetic_mean(test_deque);
std::cout << arithmetic_mean_result3 << std::endl;

// std::deque<std::deque<int>> case
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 arithmetic_mean_result4 = arithmetic_mean(test_deque2);
std::cout << arithmetic_mean_result4 << std::endl;

A Godbolt link is here.

All suggestions are welcome.

The summary information:

recursion – A recursive_count_if Function with Automatic Type Deducing from Lambda for Various Type Arbitrary Nested Iterable Implementation in C++

This is a follow-up question for A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++ and A recursive_count_if Function with Specified value_type for Various Type Arbitrary Nested Iterable Implementation in C++. After digging into the thing that detecting the argument type of a function, I found that it is possible to simplify the T1 parameter in last implementation with boost::callable_traits::args_t syntax in Boost.CallableTraits library. As the result, recursive_count_if template function can be used exactly as the following code.

std::vector<std::vector<std::string>> v = {{"hello"}, {"world"}};
auto size5 = ()(std::string s) { return s.size() == 5; };
auto n = recursive_count_if(v, size5);

The implementation of recursive_count_if function with automatic type deducing:

#include <boost/callable_traits.hpp>
//  recursive_count_if implementation
template<class T1, class T2> requires (is_iterable<T1> && std::same_as<std::tuple<std::iter_value_t<T1>>, boost::callable_traits::args_t<T2>>)
auto recursive_count_if(const T1& input, const T2 predicate)
{
    return std::count_if(input.begin(), input.end(), predicate);
}

//  transform_reduce version
template<class T1, class T2> requires (is_iterable<T1> && !std::same_as<std::tuple<std::iter_value_t<T1>>, boost::callable_traits::args_t<T2>>)
auto recursive_count_if(const T1& input, const T2 predicate)
{
    return std::transform_reduce(std::begin(input), std::end(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto& element) {
        return recursive_count_if(element, predicate);
        });
}

The used is_iterable concept:

template<typename T>
concept is_iterable = requires(T x)
{
    *std::begin(x);
    std::end(x);
};

The constraints of usage

Because the type in the input lambda function plays the role of termination condition, you can not use auto keyword as generic lambdas here. If the lambda function like ()(auto element) { } is passed in, compiling errors will pop up. If you want to use generic lambdas, maybe you can choose the previous version recursive_count_if function due to the termination condition is separated.

A Godbolt link is here.

All suggestions are welcome.

The summary information:

recursion – A recursive_count_if Function with Specified value_type for Various Type Arbitrary Nested Iterable Implementation in C++

This is a follow-up question for A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++. Thanks to Quuxplusone’s answer and G. Sliepen’s comments. Based on the mentioned std::vector<std::vector<std::string>> case, it indicates a problem about the process of unwrapping nested iterable structure. In order to make recursive_count_if function be more generic, I am trying to implement another version of recursive_count_if template function with checking container’s value_type matches specified type. The process of unwrapping nested iterable structure would keep running until the base type in container is as same as the given type T1.

//  recursive_count_if implementation
template<class T1, class T2, class T3> requires (is_iterable<T2> && std::same_as<std::iter_value_t<T2>, T1>)
auto recursive_count_if(const T2& input, const T3 predicate)
{
    return std::count_if(input.begin(), input.end(), predicate);
}

//  transform_reduce version
template<class T1, class T2, class T3> requires (is_iterable<T2> && !std::same_as<std::iter_value_t<T2>, T1>)
auto recursive_count_if(const T2& input, const T3 predicate)
{
    return std::transform_reduce(std::begin(input), std::end(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto& element) {
        return recursive_count_if<T1>(element, predicate);
        });
}

The test cases for this version recursive_count_if template function:

//  std::vector<std::vector<int>> case
std::vector<int> test_vector{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::vector<decltype(test_vector)> test_vector2;
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);

// use a lambda expression to count elements divisible by 3.
int num_items1 = recursive_count_if<int>(test_vector2, ()(int i) {return i % 3 == 0; });
std::cout << "#number divisible by three: " << num_items1 << 'n';

//  std::deque<std::deque<int>> case
std::deque<int> test_deque;
test_deque.push_back(1);
test_deque.push_back(2);
test_deque.push_back(3);

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);

// use a lambda expression to count elements divisible by 3.
int num_items2 = recursive_count_if<int>(test_deque2, ()(int i) {return i % 3 == 0; });
std::cout << "#number divisible by three: " << num_items2 << 'n';

//  std::vector<std::vector<std::string>> case
std::vector<std::vector<std::string>> v = { {"hello"}, {"world"} };
auto size5 = ()(std::string s) { return s.size() == 5; };
auto n = recursive_count_if<std::string>(v, size5);
std::cout << "n:" << n << std::endl;

The output of std::vector<std::vector<std::string>> case is:

n:2

Besides the std::vector<std::vector<std::string>> case, you can also play this recursive_count_if template function like this:
(test_vector2 is from the above usage)

//  std::vector<std::vector<std::vector<int>>> case
std::vector<decltype(test_vector2)> test_vector3;
test_vector3.push_back(test_vector2);
test_vector3.push_back(test_vector2);
test_vector3.push_back(test_vector2);
std::cout << recursive_count_if<decltype(test_vector2)>(test_vector3,
    (test_vector2)(auto& element)
    {
        return std::equal(element.begin(), element.end(), test_vector2.begin());
    }) << std::endl;

A Godbolt link is here.

All suggestions are welcome.

The summary information:

  • Which question it is a follow-up to?

    A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++

  • What changes has been made in the code since last question?

    The previous version recursive_count_if template function is hard to deal with std::vector<std::vector<std::string>> case. The experimental improved code has been proposed here.

  • Why a new review is being asked for?

    In order to perform container’s value_type matching structure, the std::same_as syntax and std::iter_value_t syntax are used here. The getting container’s value_type part is handled by std::iter_value_t and the type matching part is handled by std::same_as. I am not sure if this is a good implementation.

    On the other hand, although the separated template parameter T1 plays the role of termination condition well, I am trying to deduce the type T1 form the given SFINAE-friendly lambda function (const T3 predicate here, assume that the given lambda function is SFINAE-friendly without something including auto syntax) so that making the following usage possible (just like the same usage in Quuxplusone’s answer ).

    //  std::vector<std::vector<std::string>> case
    std::vector<std::vector<std::string>> v = { {"hello"}, {"world"} };
    auto size5 = ()(std::string s) { return s.size() == 5; };
    auto n = recursive_count_if(v, size5);            //  the `<std::string>` is no needed to pass in again.
    std::cout << "n:" << n << std::endl;
    

    I’ve checked some discussions about getting the type of a lambda argument, including Can we get the type of a lambda argument?, Is it possible to retrieve the argument types from a (Functor member’s) function signature for use in a template?, Getting the type of lambda arguments and C++ template deduction from lambda. I think that I have no idea about how to deduce the type T1 automatically. Is it possible done with std::function like the experimental code as below?

    template<class T1, class T2, class T3> requires (is_iterable<T1> && std::same_as<std::iter_value_t<T1>, T3>)
    auto recursive_count_if(const T1& input, const std::function<T2(T3)> predicate)
    {
      //...
    }
    

    However, I think that maybe T3 is not the input type of the passed lambda function in the above structure based on some experiments. If I misunderstand something, please tell me. Moreover, please give me some hints or examples if there is any other better way.

    If there is any further possible improvement, please let me know.

recursion – A recursive_count_if Function For Various Type Arbitrary Nested Iterable Implementation in C++

This is a follow-up question for A recursive_count Function For Various Type Arbitrary Nested Iterable Implementation in C++. Thanks to G. Sliepen’s answer. Based on the mentioned suggestion, the naming of the function for getting the element count in arbitrary nested iterables is updated into recursive_size. Here, I am trying to implement the functions (recursive_count and recursive_count_if) which purpose are similar to std::count and std::count_if and can be used in various type arbitrary nested iterable things. In the template function recursive_count, the first parameter is an input nested iterable object and the second parameter is the target value to search for.

//  recursive_count implementation
template<class T1, class T2> requires (!is_elements_iterable<T1> && is_iterable<T1>)
auto recursive_count(const T1& input, const T2 target)
{
    return std::count(input.begin(), input.end(), target);
}

//  for loop version
template<class T1, class T2> requires (is_elements_iterable<T1>)
auto recursive_count(const T1& input, const T2 target)
{
    size_t output{};
    for (auto &element : input)
    {
        output += recursive_count(element, target);
    }
    return output;
}

In the template function recursive_count_if, the first parameter is also an input nested iterable object and the second parameter is a unary predicate which returns ​true for the required elements.

//  recursive_count_if implementation
template<class T1, class T2> requires (!is_elements_iterable<T1> && is_iterable<T1>)
auto recursive_count_if(const T1& input, const T2 predicate)
{
    return std::count_if(input.begin(), input.end(), predicate);
}

//  for loop version
template<class T1, class T2> requires (is_elements_iterable<T1>)
auto recursive_count_if(const T1& input, const T2 predicate)
{
    size_t output{};
    for (auto &element : input)
    {
        output += recursive_count_if(element, predicate);
    }
    return output;
}

Some test cases for recursive_count template function:

//  std::vector<std::vector<int>> case
std::vector<int> test_vector{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::vector<decltype(test_vector)> test_vector2;
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);

// determine how many integers in a std::vector<std::vector<int>> match a target value.
int target1 = 3;
int target2 = 5;
int num_items1 = recursive_count(test_vector2, target1);
int num_items2 = recursive_count(test_vector2, target2);
std::cout << "number: " << target1 << " count: " << num_items1 << 'n';
std::cout << "number: " << target2 << " count: " << num_items2 << 'n';

// std::deque<std::deque<int>> case
std::deque<int> test_deque;
test_deque.push_back(1);
test_deque.push_back(2);
test_deque.push_back(3);

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);

// determine how many integers in a std::deque<std::deque<int>> match a target value.
int num_items3 = recursive_count(test_deque2, target1);
int num_items4 = recursive_count(test_deque2, target2);
std::cout << "number: " << target1 << " count: " << num_items3 << 'n';
std::cout << "number: " << target2 << " count: " << num_items4 << 'n';

Some test cases for recursive_count_if template function:

//  std::vector<std::vector<int>> case
std::vector<int> test_vector{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::vector<decltype(test_vector)> test_vector2;
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);
test_vector2.push_back(test_vector);

// use a lambda expression to count elements divisible by 3.
int num_items1 = recursive_count_if(test_vector2, ()(int i) {return i % 3 == 0; });
std::cout << "#number divisible by three: " << num_items1 << 'n';

// std::deque<std::deque<int>> case
std::deque<int> test_deque;
test_deque.push_back(1);
test_deque.push_back(2);
test_deque.push_back(3);

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);

// use a lambda expression to count elements divisible by 3.
int num_items2 = recursive_count_if(test_deque2, ()(int i) {return i % 3 == 0; });
std::cout << "#number divisible by three: " << num_items2 << 'n';

A Godbolt link is here.

All suggestions are welcome.

The summary information:

  • Which question it is a follow-up to?

    A recursive_count Function For Various Type Arbitrary Nested Iterable Implementation in C++

  • What changes has been made in the code since last question?

    • The function for getting the element count in arbitrary nested iterables is renamed into recursive_size.

    • Besides the total element count, I am trying to implement the functions (recursive_count and recursive_count_if) which purpose are similar to std::count and std::count_if and can be used in various type arbitrary nested iterable things here.

  • Why a new review is being asked for?

    As similar as G. Sliepen’s answer mentioned, there is another version of the last overload recursive_count template function implementation with std::transform_reduce:

    //  transform_reduce version
    template<class T1, class T2> requires (is_elements_iterable<T1>)
    auto recursive_count(const T1& input, const T2 target)
    {
        return std::transform_reduce(std::begin(input), std::end(input), std::size_t{}, std::plus<std::size_t>(), (target)(auto& element) {
            return recursive_count(element, target);
            });
    }
    

    Also, there is another version of the last overload recursive_count_if template function implementation with std::transform_reduce:

    //  transform_reduce version
    template<class T1, class T2> requires (is_elements_iterable<T1>)
    auto recursive_count_if(const T1& input, const T2 predicate)
    {
        return std::transform_reduce(std::begin(input), std::end(input), std::size_t{}, std::plus<std::size_t>(), (predicate)(auto& element) {
            return recursive_count_if(element, predicate);
            });
    }
    

    I am wondering which version is more readable.

    A Godbolt link for this (using std::transform_reduce) version is here.

    If there is any possible improvement, please let me know.

recursion – A recursive_transform Function For Various Type Nested Iterable With std::variant Implementation in C++

This is a follow-up question for A TransformAll Function For Various Type Arbitrary Nested Iterable Implementation in C++. The following code is the improved version based on G. Sliepen’s answer. In order to match the conventions of the STL, the function named recursive_transform here uses the is_iterable concept and the is_element_iterable concept. Moreover, the copy operation of the input is avoided by updating (_Func)(auto element)->auto into (_Func)(auto& element) and the redundant part in this lambda function ->auto has been removed. Although the code is improved, I found that there are some cases which the previous version TransformAll function is hard to deal with. One of those cases is the nested iterable ranges with std::variant. I want to focus on this case, such as std::vector<std::variant<long double>>. First of all, the additional concept is_element_variant is included for determining the type of elements in iterable container is std::variant or not. I think there may be another better implementation to this is_element_variant concept. However, the method I surveyed How to check if template argument is std::variant? isn’t deal with this with c++-concepts. I prefer to work with concept here and the experimental code is as below. If there is any suggestion about how to improve this is_element_variant concept, please let me know.

template<typename T>
concept is_element_variant = requires(T x)
{
    x.begin()->index();
    x.begin()->valueless_by_exception();
};

The part of the template function recursive_transform which handle the std::variant structure:

template<class T, class _Fn> requires is_iterable<T> && is_element_variant<T>
static T recursive_transform(const T _input, _Fn _Func);       //  Deal with the iterable case which its element is std::variant

template<class T, class _Fn> requires is_iterable<T> && is_element_variant<T>
static inline T recursive_transform(const T _input, _Fn _Func)
{
    T returnObject = _input;
    
    std::transform(_input.begin(), _input.end(), returnObject.begin(), 
        (_Func)(typename std::iterator_traits<typename T::iterator>::value_type x)->
        typename std::iterator_traits<typename T::iterator>::value_type
        {
            return std::visit((_Func)(auto&& arg) -> typename std::iterator_traits<typename T::iterator>::value_type
                    {
                        return _Func(arg);
                    }, x);
        });
    return returnObject;
}

The other parts:

template<typename T>
concept is_iterable = requires(T x)
{
    x.begin();      // must have `x.begin()` 
    x.end();        // and `x.end()` 
};

template<typename T>
concept is_element_iterable = requires(T x)
{
    x.begin()->begin();
    x.end()->end();
};

template<class T, class _Fn> requires is_iterable<T>
static T recursive_transform(const T _input, _Fn _Func);       //  Deal with the iterable case like "std::vector<long double>"

template<class T, class _Fn> requires is_iterable<T>
static inline T recursive_transform(const T _input, _Fn _Func)
{
    T returnObject = _input;

    std::transform(_input.begin(), _input.end(), returnObject.begin(), _Func);
    return returnObject;
}

template<class T, class _Fn> requires is_iterable<T> && is_element_iterable<T>
static T recursive_transform(const T _input, _Fn _Func);

template<class T, class _Fn> requires is_iterable<T> && is_element_iterable<T>
static inline T recursive_transform(const T _input, _Fn _Func)
{
    T returnObject = _input;
    std::transform(_input.begin(), _input.end(), returnObject.begin(),
        (_Func)(auto& element)
        {
            return recursive_transform(element, _Func);
        }
    );
    return returnObject;
}

int main()
{
    std::vector<long double> testVector1;
    testVector1.push_back(1);
    testVector1.push_back(20);
    testVector1.push_back(-100);
    std::cout << recursive_transform(testVector1, ()(long double x)->long double { return x + 1; }).at(0) << std::endl;

    std::vector<long double> testVector2;
    testVector2.push_back(10);
    testVector2.push_back(90);
    testVector2.push_back(-30);

    std::vector<std::vector<long double>> testVector3;
    testVector3.push_back(testVector1);
    testVector3.push_back(testVector2);
    std::cout << recursive_transform(testVector3, ()(long double x)->long double { return x + 1; }).at(1).at(1) << std::endl;
    
    std::vector<std::variant<long double>> testVector4;
    testVector4.push_back(1);
    testVector4.push_back(20);
    testVector4.push_back(-100);

    auto operation_to_element = ()(long double number) { return number + 2; };

    std::visit(()(auto&& arg) {std::cout << arg; },         //  For printing
        recursive_transform(testVector4, operation_to_element).at(0)
    );

    return 0;   
}

All suggestions are welcome.

The summary information:

  • Which question it is a follow-up to?

    A TransformAll Function For Various Type Arbitrary Nested Iterable Implementation in C++

  • What changes has been made in the code since last question?

    • Rename function to recursive_transform to match the conventions of the STL.
    • The copy operation of the input is avoided by updating auto &element.
    • Remove the redundant part in lambda function ->auto
  • Why a new review is being asked for?

    I think the concept is_element_variant may be improved and I am looking forward to any suggestion for possible improvement ways. Moreover, in my opinion of the part of the template function recursive_transform which handle the std::variant structure, implementation here is complex, there are two nested lambda function. If there is any possible to simplify this, please let me know.

python 3.x – El parametro inicializador de reduce() en la suma de elementos de un iterable

Una consulta con respecto a este código:

from functools import reduce

def sum_even(it):
    return reduce(lambda x, y: x + y if not y % 2 else x, it,0)
    
print(sum_even((1, 2, 3, 4)))

Porque al no agregar el tercer parametro de reduce() se suma el primer elemento impar de la lista?

reactjs – TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator)) useContext

Trying to test using context and states, and getting this error.
The error occurs with the line of code below that has useContext(InventoryContext). I have already wrapped all of my components with InventoryProvider.

const AddInvItem = () => {
  const (name, setName) = useState("");
  const (price, setPrice) = useState("");
  const (products, setProducts) = useContext(InventoryContext);

  const updateName = (e) => {
    setName(e.target.value);
  };
  const updatePrice = (e) => {
    setPrice(e.target.value);
  };

  const addItem = (e) => {
    e.preventDefault();
    setProducts((prevProducts) => (
      ...prevProducts,
      { productName: name, purchasePrice: price },
    ));
  };
  return (
    <form onSubmit={addItem}>
      <input
        type="text"
        name="productName"
        value={name}
        onChange={updateName}
      />
      <input type="text" name="price" value={price} onChange={updatePrice} />
      <button>Submit</button>
    </form>
  );
};

export default AddInvItem;

Context:

import React, { useState, createContext } from "react";

export const InventoryContext = createContext();

export const InventoryProvider = (props) => {
  const (products, setProducts) = useState((
    {
      productName: "test",
      purchasePrice: "$0",
      id: 1,
    },
  ));
  return (
    <InventoryContext.Provider items={(products, setProducts)}>
      {props.children}
    </InventoryContext.Provider>
  );
};

Any ideas?