PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label iterator. Show all posts
Showing posts with label iterator. Show all posts

Monday, November 7, 2022

[FIXED] How Set.contains() decides whether it's a subset or not?

 November 07, 2022     hashset, iterator, java, set, subset     No comments   

Issue

I expect the following code would give me a subset and a complementary set.

But actually, the result shows that "Error: This is not a subset!"

What it.next() get and how to revise my code to get the result I want? Thanks!

package Chapter8;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Three {
    int n;
    Set<Integer> set = new HashSet<Integer>();

    public static void main(String args[]) {
        Three three = new Three(10);
        three.display(three.set);
        Set<Integer> test = new HashSet<Integer>();
        Iterator<Integer> it = three.set.iterator();
        while(it.hasNext()) {
            test.add(it.next());
            three.display(test);
            three.display(three.complementarySet(test));
        }

    }

    boolean contains(Set<Integer> s) {
        if (this.set.contains(s))
            return true;
        else 
            return false;
    }

    Set<Integer> complementarySet(Set<Integer> s) {
        if(this.set.contains(s)){
            Set<Integer> result = this.set;
            result.removeAll(s);
            return result;
        }
        else {
            System.out.println("Error: This is not a subset!");
            return null;
        }
    }

    Three() {
        this.n = 3;
        this.randomSet();
    }

    Three(int n) {
        this.n = n;
        this.randomSet();
    }

    void randomSet() {
        while(set.size() < n) {
            set.add((int)(Math.random()*10));
        }
    }

    void display(Set<Integer> s) {
        System.out.println("The set is " + s.toString());
    }
}

Solution

Your problem is in this part:

set.contains(s)

that doesn't do what you think it does, it doesn't take as an argument another Set to see if its members are contained in the firstset. It rather looks if the argument passed it is in the Set.

You need to iterate over the "contained" set and use set.contains(element) for each element in the contained set.



Answered By - morgano
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can i properly use the .find() function from set in C++?

 November 07, 2022     c++, find, iterator, set, struct     No comments   

Issue

Here is the struct for 'point'

struct point
{
  double x;
  double y;
};

and here is the function that produces an error, there is an issue with my use of .find() as show in the pic below. When I hover over the error it says "In template: invalid operands to binary expression ('const point' and 'const point')"

bool isChecked(point left, point right, set<vector<point>>const& inSet)
{
  // Check both possible arrangements of points
  vector<point> tmp1 = {left, right};
  vector<point> tmp2 = {right, left};

  // .find() returns an iterator up to the element found
  // If not found, return element after last, .end()
  auto first = inSet.find(tmp1);
  auto second = inSet.find(tmp2);

  // Check if elements were checked already
  if (first != inSet.end() || second != inSet.end())
      return true;

  return false;
}

Here is the error provided by compiler:

C:/msys64/mingw64/include/c++/12.2.0/bits/predefined_ops.h:45:23: error: no match for 'operator<' (operand types are 'const point' and 'const point')
   45 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
In file included from C:/msys64/mingw64/include/c++/12.2.0/string:47:
C:/msys64/mingw64/include/c++/12.2.0/bits/stl_iterator.h:1246:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __normal_iterator<_IteratorL, _Container>&, const __normal_iterator<_IteratorR, _Container>&)'
 1246 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
      |     ^~~~~~~~
C:/msys64/mingw64/include/c++/12.2.0/bits/stl_iterator.h:1246:5: note:   template argument deduction/substitution failed:
C:/msys64/mingw64/include/c++/12.2.0/bits/predefined_ops.h:45:23: note:   'const point' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
   45 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
C:/msys64/mingw64/include/c++/12.2.0/bits/stl_iterator.h:1254:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __normal_iterator<_Iterator, _Container>&, const __normal_iterator<_Iterator, _Container>&)'
 1254 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
      |     ^~~~~~~~
C:/msys64/mingw64/include/c++/12.2.0/bits/stl_iterator.h:1254:5: note:   template argument deduction/substitution failed:
C:/msys64/mingw64/include/c++/12.2.0/bits/predefined_ops.h:45:23: note:   'const point' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
   45 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
ninja: build stopped: subcommand failed.

Solution

you need to add this to your code:

bool operator<(const point& lhs, const point& rhs)
{
  return lhs.x < rhs.x;
}

to overload the < operator.

and then you write your function and you can write it like this:

bool isChecked(point left, point right, set<vector<point>> inSet)
{
  // Check both possible arrangements of points
  vector<point> tmp1 = {left, right};
  vector<point> tmp2 = {right, left};

    if (inSet.find(tmp1) != inSet.end() || inSet.find(tmp2) != inSet.end())
    {
        return true;
    }
    else
    {
        return false;
    }
}


Answered By - Parisa.H.R
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, November 1, 2022

[FIXED] Why does my calculation of the middle of two iterators fail with sigsegv?

 November 01, 2022     c++, iterator, pivot, quicksort     No comments   

Issue

I have implemented Quicksort from Wikipedia. The code calculates the middle pivot value of two iterators with ptrdiff_t. But I want to calculate the middle iterator not the value. The following code works. But if pivot_mid() is used it can hang or end with sigsegv.

#include <array>    // std::array
#include <cassert>  // assert
#include <cstddef>  // ptrdiff_t
#include <ctime>    // std::time
#include <iostream> // std::cout
#include <iterator> // std::ostream_iterator

template <typename T, typename Compare, typename Partition>
void quicksort_hoare_from_cormen_et_al(T first, T after_last, Compare comp, Partition part) {
    // if p < r
    if (std::distance(first, after_last) > 1) {
        // q = Partition(A,p,r)
        T pivot = part(first, after_last, comp);
        // Quicksort(A,p,q) // the pivot IS included
        quicksort_hoare_from_cormen_et_al(first, pivot + 1, comp, part);
        assert(std::is_sorted(first, pivot + 1, comp));
        // Quicksort(A,q+1,r)
        quicksort_hoare_from_cormen_et_al(pivot + 1, after_last, comp, part);
        assert(std::is_sorted(pivot + 1, after_last, comp));
    }
}

auto pivot_mid = []<typename T>(T first, T after_last) {
    return first + (after_last - first) / 2;
//  return first + (std::distance(first, after_last) / 2);
//  return first + (std::distance(first, std::prev(after_last)) / 2);
//  return std::next(first, (std::distance(first, std::prev(after_last)) / 2));
//  return std::next(first, std::distance(first,after_last)/2);
};

template<typename T, typename Compare>
T partition_hoare_from_wikipedia(T first, T after_last, Compare comp) {
    // pivot := A[floor((hi + lo) / 2)]
//  auto pivot = pivot_mid(first, after_last);      // this is an iterator for the pivot // I WANT THIS
    ptrdiff_t right = (after_last - first) - 1;
    ptrdiff_t left = 0;
    auto pivot = first[left + (right - left) / 2];  // this is the value of the pivot
    
    // i := lo - 1
    auto i = first - 1;
    // j := hi + 1
    auto j = after_last;
    
    // loop forever
    while (true) {
        // do i := i + 1 while A[i] < pivot
        do {++i;} while (comp(*i, pivot));  // if pivot is an iterator, then change to *pivot
        // do j := j - 1 while A[j] > pivot
        do {--j;} while (comp(pivot, *j));  // if pivot is an iterator, then change to *pivot
        
        // if i ≥ j then return j
        if (i >= j) return j;
        
        // swap A[i] with A[j]
        std::swap(*i, *j);
    }
}

template <class T, std::size_t N>
std::ostream& operator<<(std::ostream& o, const std::array<T, N>& arr) {
    std::copy(arr.cbegin(), arr.cend(), std::ostream_iterator<T>(o, " "));
    return o;
}

int main() {
//    std::array<int,5> arr = {5,4,3,2,1};
    std::array<int,(1<<2)+1> arr;
    std::srand(std::time(nullptr));
    std::generate(arr.begin(), arr.end(), [](){return 1 + std::rand()/((RAND_MAX + 1u)/10);});
    std::cout << arr << std::endl;
    
    quicksort_hoare_from_cormen_et_al(arr.begin(), arr.end(), std::less<int>(), [](auto a, auto b, auto c){
        return partition_hoare_from_wikipedia(a,b,c);
    });
    
    std::cout << arr << std::endl;
    return 0;
}

Here is a live demo

There seems to be a subtle difference between:

ptrdiff_t right = (after_last - first) - 1;
ptrdiff_t left = 0;
auto pivot = first[left + (right - left) / 2];

and:

auto pivot_mid = []<typename T>(T first, T after_last) {
    return first + (after_last - first) / 2;
}

But where is it?

UPDATE #1: I have found something strange. It's possible to get an iterator and a value like this:

auto pivot_ = std::next(first, left + (right - left) / 2); // iterator
auto pivot = *pivot_; // value

If we use pivot in the two while loops, then the code runs fine. But with *pivot_ the code hangs. This makes no sense.

ANSWER: Alex has found the reason. swap(*i, *j) can change the value for the iterator pivot_. This is the reason why it must be a value. The pseudo code in Wikipedia also has a comment behind pivot: The value in the middle of the array. I should have strictly followed that.

NOTE: I wrote a comment in the pseudcode in Wikipedia that pivot must not be a pointer or iterator.


Solution

Update:

After reviewing the behavior of the code under my debugger I've realized the root cause: The inner loops cannot use a pointer to the pivot.

When the array is modified by swapping i and j, the actual value of the element the pivot points to may change. This fundamentally breaks the algorithm, causing the resulting array to be only mostly sorted (like a set of sorted arrays got concatenated instead of merged).

The correct solution is to use the value directly, like so:

template<typename T, typename Compare>
T partition_hoare_from_wikipedia(T first, T after_last, Compare comp)
{
    // pivot := A[floor((hi + lo) / 2)]
    auto pivot = *pivot_mid(first, after_last);
    // i := lo - 1
    auto i = first;
    // j := hi + 1
    auto j = after_last;

    // loop forever
    while(true)
    {
        // do i := i + 1 while A[i] < pivot
        while(comp(*i, pivot))
        {
            ++i;
        }
        // do j := j - 1 while A[j] > pivot
        do
        {
            --j;
        } while(comp(pivot, *j));
        // if i ≥ j then return j
        if(i >= j) return j;
        // swap A[i] with A[j]
        std::swap(*i, *j);
    }
}

You have two main issues in the code you provided.

First, your midpoint calculation function for iterators is off by one, which causes a stack overflow. Instead of:

auto pivot_mid = []<typename T>(T first, T after_last) {
    return first + (after_last - first) / 2;
}

This should be:

auto pivot_mid = []<typename T>(T first, T after_last) {
    return first + ((after_last - first) - 1) / 2;
}

This matches the behavior of your value pivot calculation.

Second, your algorithm fails to account for the possibility that first is already at the head, which will cause the computation of i to underflow the iterator. This crashes your program.

To avoid this, we can adopt slightly different logic for the first increment loop. The original code decremented i, then incremented it again before doing a comparison. We can instead remove the first decrement, and reorder the loop to do the comparison first before the increment so we don't accidentally skip the first element:

    // i := lo - 1
    auto i = first;
    // j := hi + 1
    auto j = after_last;
    
    // loop forever
    while (true) 
    {
        // do i := i + 1 while A[i] < pivot
        while (comp(*i, *pivot))
        {
              ++i;
        }

These corrections allow the code to function properly under my debugger (MSVC 2019).

Note that this still does not fully fix your code - while an array of 5 elements works fine for this system, if you extend the number of elements out, the algorithm as written fails to sort the array. Even with as few as ten elements the array would sometimes fail to sort properly.

You will need to pick apart the algorithm as it runs to identify the issue with the sorting. I recommend the following sequence:

9, 7, 2, 4, 2, 4, 10, 7, 7, 4

This will fail to sort when your algorithm is run on it, producing the "sorted" array of:

2, 2, 4, 7, 4, 4, 9, 7, 7, 10



Answered By - Alex
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, October 23, 2022

[FIXED] How can I make 2 c++ classes know about each other's data members?

 October 23, 2022     c++, class, datamember, iterator     No comments   

Issue

My assignment is to make a class that acts like a standard library List. I am unable to get the iterator to work properly, because it must access the tail of the linked list when decrementing from the end. Here is a section of my header file:

typedef int T;//for now; eventually will be templated
class list;//**forward declaration, doesn't let other classes know about _tail.**
class Node
{
    //this works fine; class definition removed to make post shorter
};
class list_iterator
{
    private:
        Node* _node;
        list* _list;
    public:
        //constructor
        list_iterator& operator--(){_node=_node?(_node->_prev):(_list->_tail);return *this;}
        //some other declarations
};
class list
{
    friend class list_iterator;
    private:
        Node/*<T>*/ *_head,***_tail**;
        int _size;
    public:
        typedef list_iterator iterator;
        //some constructors and other method declarations
        iterator begin() const {iterator it(_head);return it;}
        iterator end() const {iterator it(0);return it;}
        //more method declarations
};

I tried to bold the important parts, but it is just surrounding them with asterisks. NOTE: Most of the member functions are defined in the cpp file; they all happen to be removed for a short post.


Solution

You just need to move the method definition of operator-- out of the class and put it after list (or in the source file (probably a better idea. Leave the header file for declarations)).

Note: Leave the declaration inside list_iterator

class list_iterator
{
    /* STUFF */
    list_iterator& operator--();
 };
class list
{ 
     /*  STUFF */ 
};

// Now list_iterator::operator-- can see all the members of list.
list_iterator& list_iterator::operator--()
{
    _node=_node?(_node->_prev):(_list->_tail);
    return *this;
}

Unlike what some other answers suggest. Friendship does NOT break encapsulation. In fact in increases encapsulation (when done correctly) by making the friend part of the classes interface. It does however tightly bind the friend to the class.

This is exactly what you want for iterators. For the iterator to work efficiently it needs to know the internals of the class so it is usually a friend (or an internal class). It increases the usability of the class without exposing the internal workings of the class at the cost that it tightly couples the iterator to the class (so if you change the class you will need to change the implementation of the iterator (but this is not unexpected)).



Answered By - Martin York
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, September 20, 2022

[FIXED] What exactly happens when we write if(mp.find()==mp.end())

 September 20, 2022     c++, hashmap, iterator     No comments   

Issue

I'm currently learning hashmap, I'm facing trouble understanding the iterators, while using it in if statements.

For example,


int main ()
{
  std::map<char,int> mymap;
  std::map<char,int>::iterator it;
  mymap['a']=50;
  mymap['b']=100;
  mymap['c']=150;
  mymap['d']=200;

  it = mymap.find('d');
  if (it == mymap.end())
    mymap.erase (it);
  if (it != mymap.end())
    mymap.erase (it);
}
    

I am able to understand what happens in the second if statement. Can anyone explain what exactly does the first if statement will do? When I tried to erase the value of d it does nothing. Can someone explain the difference between the two if statements?


Solution

From std::map::erase

The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos.

Since the below part of the code fails to comply with the above

if (it == mymap.end())
    mymap.erase (it);

the program will have undefined behavior in case it == mymap.end() - which means that it could do just about anything, including nothing or crashing. Avoid undefined behavior like the plague.


The other part is the correct way to do it. Make sure that it is not the end() iterator before using it to erase an element.

if (it != mymap.end())
    mymap.erase (it);

Can someone explain the difference between the two if statements?

it = mymap.find('d'); searches for 'd' in the map. If 'd' is found, it returns an iterator to the place in the map where the key 'd' was found. If 'd' is not found, it returns the end() iterator. The end() iterator in all standard containers (possible exception: basic_string), and even plain arrays, isn't dereferenceable. Using an array to illustrate:

int a[] = {7,8,9};

Memory layout:

addr   a+0 a+1 a+2 a+3
      +---+---+---+---
value | 7 | 8 | 9 | (out of bounds)
      +---+---+---+---
        ^           ^
        |           |
std::begin(a)   std::end(a)

The end() iterator for a plain array points one step after the last element and dereferencing it would mean that you peek out of bounds, with undefined behavior as a result. It's similar for maps, only that the memory layout isn't as simple as for plain arrays.

The difference between the two if statements is therefore that one makes sure that the iterator can be deferenced before using it to erase - and the other makes sure that the iterator is not an iterator that should be deferenced (or used with erase), before using it with erase anyway.



Answered By - Ted Lyngmo
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 19, 2022

[FIXED] How to return the next element from a spliterator in java

 September 19, 2022     consumer, iterator, java, java-8, spliterator     No comments   

Issue

I want to get the next element from a spliterator, not just "perform action" on the next element. For example by implementing the following method

<T> T getnext(Spliterator<T> s) {

}

All search results I found just said that tryAdvance() was like a combination of an iterators hasNext() and next(), except that is a BIG LIE because I can't get next element, just "perform action on next element".


Solution

You can wrap the item in a list and then return from that list:

    public static <T> T getNext(Spliterator<T> spliterator) {
        List<T> result = new ArrayList<>(1);

        if (spliterator.tryAdvance(result::add)) {
            return result.get(0);
        } else {
            return null;
        }
    }

To make it more obvious to the caller that this is an operation that may return null, consider returning Optional:

    public static <T> Optional<T> getNext(Spliterator<T> spliterator) {
        final List<T> result = new ArrayList<>(1);

        if (spliterator.tryAdvance(result::add)) {
            return Optional.of(result.get(0));
        } else {
            return Optional.empty();
        }
    }


Answered By - Felix
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, July 23, 2022

[FIXED] How do I iterate over a JSON list? (rust)

 July 23, 2022     iterator, json, rust     No comments   

Issue

I am loafing a gltf asset (basically a big json file). I want to iterate over one of the fields, i.e. I am doing this:

let data = fs::read_to_string("Assets/werewolf_animated.gltf").expect("Unable to read file");
    let json: serde_json::Value =
        serde_json::from_str(&data).expect("JSON was not well-formatted");

    for skin in json["skins"].into()
    {
        println!("{:?}", skin["inverseBindMatrices"]);
    }

But apparently rust cannot infer the type, I get:

 println!("{:?}", skin["inverseBindMatrices"]);
   |                          ^^^^ cannot infer type

How can I iterate over every entry in the skins json array?

For what is worth this is what the specific field looks like in the json file:

"skins" : [
        {
            "inverseBindMatrices" : 5,
            "joints" : [
                64,
                53,
                52,
                51,
                2,
            ],
            "name" : "Armature"
        }
    ],

Solution

Value is an enum of all of the possible types of JSON values, so you have to handle the non-array cases as well (null values, booleans, numbers, strings, and objects). The helper Value::as_array() method returns an Option which is None in the non-array cases:

if let Some(skins) = json["skins"].as_array() {
    for skin in skins {
        // ...
    }
}

In this case, this is pretty much equivalent to:

if let serde_json::Value::Array(skins) = json["skins"] {
    for skin in skins {
        // ...
    }
}

If you want to signal an error via Result when this value isn't an array, you can combine Value::as_array() with Option::ok_or(). Here is an example, which assumes the presence of a custom error enum DataParseError:

for skin in json["skins"].as_array().ok_or(DataParseError::SkinsNotAnArray)? {
    // ...
}


Answered By - cdhowie
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 10, 2022

[FIXED] How do I iterate over the fields of a ref object in nim?

 July 10, 2022     iterator, nim-lang, reference     No comments   

Issue

I have a ref object type and would like to iterate over all of its fields and echo them out.

Here an example of what I want:

type Creature* = ref object
    s1*: string
    s2*: Option[string]
    n1*: int
    n2*: Option[int]
    n3*: int64
    n4*: Option[int64]
    f1*: float
    f2*: Option[float]
    b1*: bool
    b2*: Option[bool]


var x = Creature(s1: "s1", s2: some("s2"), n1: 1, n2: some(1), n3: 2, n4: some(2.int64), f1: 3.0, f2: some(3.0), b1: true, b2: some(true))

for fieldName, fieldValue in x.fieldPairs:
  echo fieldName

However, doing so causes this compiler error:

Error: type mismatch: got <Creature>
but expected one of:
iterator fieldPairs[S: tuple | object; T: tuple | object](x: S; y: T): tuple[
    key: string, a, b: RootObj]
  first type mismatch at position: 1
  required type for x: S: tuple or object
  but expression 'x' is of type: Creature
iterator fieldPairs[T: tuple | object](x: T): tuple[key: string, val: RootObj]
  first type mismatch at position: 1
  required type for x: T: tuple or object
  but expression 'x' is of type: Creature

expression: fieldPairs(x)

Going through the documentation, there appear to be no iterators for ref object types, only for object types. If that's the case, then how do you iterate over ref object types?


Solution

If you want to use iterators, you need to de-reference the ref-type that you want to iterate over! This may also apply to any other proc that expects an object parameter, but that you want to use with a ref object instance.

In nim, the de-referencing operator is [].

So in order to work, the instance x of the ref object type Creature needs to be de-referenced before iterating over it:

for fieldName, fieldValue in x[].fieldPairs:
  echo fieldName

This will also work with any proc you write, for example like this:

proc echoIter(val: object) =
  for fieldName, fieldValue in val.fieldPairs:
    echo fieldName

echoIter(x[])


Answered By - Philipp Doerner
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 6, 2022

[FIXED] How to have by-reference locals in coroutines in Unity?

 July 06, 2022     c#, coroutine, iterator, pass-by-reference, unity3d     No comments   

Issue

I have some functions that take in an Enemy instance and change one of its fields. The Enemy class has some basic fields like speed, damage, attack range. Each function just stores one of the normal value of the enemy and then change the current field to some value for an amount of time and then change it back to the normal state (I code in Unity and use Coroutine for this). The difference is which field to store (speed or damage or attack range, etc). So I want to make a single function that takes in a delegate that returns the field that it wants to change:

delegate ref float Stat();

private IEnumerator EnemyStatModify(Enemies enemy, float duration, float percent, Stat stat)
{
    ref float enemyStat = ref stat();
    float normalStat = enemyStat;
    enemyStat *= (1 - percent);
    yield return new WaitForSeconds(duration);
    enemyStat = normalStat;
}

and then use it like this

EnemyStatModify(enemy, state.duration, state.timeBtwHits, () => ref enemy.speed);

EnemyStatModify(enemy, state.duration, state.timeBtwHits, () => ref enemy.damage);

But Iterators can't have by-reference locals. How to bypass this?


Solution

You actually don't need the return value of your delegate. You also don't need the Enemies since you don't use it in the routine anyway.

This is of course still not as beautiful as ref parameters would be but you could simply use a callback like

delegate void Stat(float newValue);


private IEnumerator EnemyStatModify(float duration, float percent, float currentValue, Stat onUpdated)
//or
//private IEnumerator EnemyStatModify(float duration, float percent, float stat, Action<float> onUpdated)
{
    onUpdated?.Invoke(currentValue * (1 - percent));

    yield return new WaitForSeconds(duration);

    onUpdated?.Invoke(currentValue);
}

and call it like

StartCoroutine(EnemyStatModify(state.duration, state.timeBtwHits, enemy.speed, (newValue) => 
{ 
    enemy.speed = newValue; 
}));

StartCoroutine(EnemyStatModify(state.duration, state.timeBtwHits, enemy.damage, (newValue) => 
{ 
    enemy.damage = newValue; 
});

Instead of the Stat you could also just use a Action<float>



Answered By - derHugo
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, June 26, 2022

[FIXED] Why does std::begin behave differently when called in a nested function

 June 26, 2022     c++, clang++, compiler-errors, iterator, linux     No comments   

Issue

I have some simple code

#include<iterator>

int main() {
    int y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    auto a = std::begin(y);
    std::cout << *a << std::endl;
    return 0;
}

Which prints out 1 as expected.

However if I do this :

void checkNested(int val [10]) {
    auto a = std::begin(val);
    std::cout << *a << std::endl;

}

int main() {
    int y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    checkNested(y);
    return 0;
}

I get compilation failures from both clang++ and g++. From clang++ specifically I get:


    auto a = std::begin(input);
             ^~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/initializer_list:89:5: note: candidate template ignored: could not match 'initializer_list<type-parameter-0-0>' against 'int *'
    begin(initializer_list<_Tp> __ils) noexcept
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/range_access.h:48:5: note: candidate template ignored: substitution failure [with _Container = int *]: member reference base type 'int *' is not a structure or union
    begin(_Container& __cont) -> decltype(__cont.begin())
    ^                                           ~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/range_access.h:58:5: note: candidate template ignored: substitution failure [with _Container = int *]: member reference base type 'int *const' is not a structure or union
    begin(const _Container& __cont) -> decltype(__cont.begin())
    ^                                                 ~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/range_access.h:87:5: note: candidate template ignored: could not match '_Tp [_Nm]' against 'int *'
    begin(_Tp (&__arr)[_Nm])
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/range_access.h:104:31: note: candidate template ignored: could not match 'valarray<type-parameter-0-0>' against 'int *'

  template<typename _Tp> _Tp* begin(valarray<_Tp>&);
                              ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/range_access.h:105:37: note: candidate template ignored: could not match 'valarray<type-parameter-0-0>' against 'int *'
  template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);

Just wanna know if there's something really obvious I'm missing here since I expected them to function the same. Thanks


Solution

An array can't be passed by value, so your array decays into a pointer when passed to checkNested(), and std::begin() is not defined for a pointer, hence the error.

void checkNested(int val [10]) is just syntax sugar for void checkNested(int *val).

If you pass the array by reference instead, then the code will work:

void checkNested(int (&val) [10])


Answered By - Remy Lebeau
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, May 9, 2022

[FIXED] How to set product to 0 if its a product over an empty list in Julia?

 May 09, 2022     empty-list, iterator, julia, list, product     No comments   

Issue

In my code I use Julia's prod() function to do a product over the elements of a list. However, sometimes that list is empty, in which case I want prod(myList) to just return 0 (or any fixed number like 1). I tried searching online, but the only things I could find were for iterators or stuff like that.

I'm using Julia version 1.5.2.


Solution

Would a simple ternary operator work for your case?

isempty(my_list) ? 0 : prod(my_list)


Answered By - Nils Gudat
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, February 13, 2022

[FIXED] CakePHP3: How to get the query result count if the result is a collection?

 February 13, 2022     cakephp, cakephp-3.0, collections, count, iterator     No comments   

Issue

I have the following code:

$sites = $this->Sites->find()
->contain([
    'Sitecategories',
    'Sitedescriptions.Languages',
    'Countries',
    'Users'
])
->where([
    'postcode LIKE' => $this->request->data['numero'] . '%'
])
->sortBy(function($row) { return substr($row->postcode, 0, 2); }, SORT_ASC);

debug($sites); displays:

object(Cake\Collection\Iterator\SortIterator) {

'count' => (int) 428

}

But I don't understand how to access to that count var.

I tried to access $sites->count() but I get the following error message:

Error: You cannot issue a count on a Collection.

Solution

Counting collections is kinda unreliable, given than they can mutate when being iterated, ie the count and the content can change, and with every iteration, changes may be reapplied for certain operations, causing the collection to possibly mutate in an unwated way (filtering, reducing, modifying contained objects, etc). Another unwanted effect may be unrewindable collections, ie they could not be iterated anymore. So that's basically why no count method is implemented.

The debug info shown there is the return value of iterator_count(), it accepts traversable objects and returns the number of elements in the iterator. Calling this will have the aforementioned side effects, the collection will be iterated and possibly mutated.

If you really need to know the count, and want to keep the collection, then you could for example compile it in beforehand, that would create a new collection based on the source data with all modifications applied, like:

$sites = $sites->compile();
$count = iterator_count($sites);

$sites can safely be reused after that point.

If you don't need the collection anymore, you could always simply convert it into an array and count that:

$sites = $sites->toArray();
$count = count($sites);

See also

  • PHP Manual > iterator_count()
  • Cookbook > Collections > Collection::compile()


Answered By - ndm
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, February 4, 2022

[FIXED] How to append to a CakePHP3 ResultSet?

 February 04, 2022     cakephp, cakephp-3.0, iterator     No comments   

Issue

I have a query (a Query object):

$joblineitems = $this->JobLineItems->find('all');

It has results (a ResultSet object):

$joblineitemsresults = $joblineitems->all();

The ResultSet object is an Iterable such that a foreach() loop will return each of the JobLineItem objects.

I simply want to add an additional result to $joblineitemsresults - specifically I want to append a $this->JobLineItems->newEntity() to the end of the results so that when I subsequently paginate $joblineitemsresults and loop through it in the view, the last object in the loop on the last page will be a blank object with the property new=true.

How can I manually append an extra result to a ResultSet object?


Solution

try this

$joblineitems = $this->JobLineItems->find('all');
$joblineitemsresults = $joblineitems->all();

$joblineitemsresults = $joblineitemsresults ->append([$this->JobLineItems->newEntity()]);
debug($joblineitemsresults ->toList());

You can see the manual for reference

pay attention in particular to the last paragraph

When appending from different sources, you can expect some keys from both collections to be the same. For example, when appending two simple arrays. This can present a problem when converting a collection to an array using toArray(). If you do not want values from one collection to override others in the previous one based on their key, make sure that you call toList() in order to drop the keys and preserve all values.

That's why I used toList() instead of toArray(). If you use toArray() you'll see the new entity override the first one.

Of course you can also transform your recordset in an array and then append the new entity to the array

$joblineitemsresults = $joblineitems->toArray();
joblineitemsresults[] = $this->JobLineItems->newEntity();


Answered By - arilia
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, January 27, 2022

[FIXED] PHP how to display folder and its content while also being able to download the content

 January 27, 2022     browser, file, filesystems, iterator, php     No comments   

Issue

So I am trying to create a file server,

Basicaly the way it should work is you have lots of folders that contain files and when you click on a file you will download it, if it is a folder you can open it and see the content inside it.

My question is how can I create such system ? I have been trying to use FilesystemIterator but I do not know how to proceed further.

this is my PHP code that I am using, this code is set inside of div element

 <?php 
        $filesInFolder = array();
        $directory = "src";
        $iterator = new FilesystemIterator($directory);

        foreach($iterator as $entry){
            $filesInFolder[] = $entry->getFilename();
        }

        foreach($filesInFolder as $file){
            echo "<a href='/$file'> $file </a>";
        }
  ?>

And this is my file structure file structure

I know that it is possible to create this, I just don't know how to create it.


Solution

So here is how you would do it. First you create a FileReader.php file like so ( I have also added Icons and file size, you will need to create icons folders where all your icons will be located)

<?php
/**
 * File reader, reads directory and outputs it in an array
 */
class FileReader {

    public function __construct(
        public string $root
    ) {}
    
    /**
     * @param string $path 
     */
    public function removeRootFromPath( $path) {
        $path = preg_replace('/' . preg_quote($this->root, '/') . '/', '', $path);
        $path = $this->cleanPath($path);
        return DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR);
    }

    /**
     * @param string $path
     */
    public function addRootToPath( $path) {
        $path = $this->removeRootFromPath($path);
        $path = ltrim($path, DIRECTORY_SEPARATOR);
        $root = rtrim($this->root, DIRECTORY_SEPARATOR);
        return $root . DIRECTORY_SEPARATOR . $path;
    }

    /**
     * @param string $dir Directory to load
     */
    public function cleanPath( $dir) {
        $sep = preg_quote(DIRECTORY_SEPARATOR, '/');
        return preg_replace('/\.\.' . $sep . '|\.' . $sep . '/', '', $dir);
    }

    /**
     * @param string $dir Directory to load
     * @return FilesystemIterator|null
     */
    public function readDirectory( $dir) {
        $dir = $this->addRootToPath($dir);

        try {
            return new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
        } catch (UnexpectedValueException $exception) {
            return null;
        }
    }

    /** 
    * @param string $size File size in bytes
    * @param int $precision File size conversion precision
    * @return string round($size, $precision).$units[$i] 
    */

    public function humanFilesize($size, $precision = 1) {
        $units = array(' B',' kB',' MB',' GB',' TB',' PB',' EB',' ZB',' YB');
        $step = 1024;
        $i = 0;
        while (($size / $step) > 0.9) {
            $size = $size / $step;
            $i++;
        }
        return round($size, $precision).$units[$i];
    }

    /** 
    * @param string $file File to load
    * @return string $type <- File type
    * @return string $image <- File image
    */
    public function returnFileExtensionAndImage($file) {

        $val = strtolower($file);
        switch($val) {
        case "avi":
            $type = "Video file";
            $image = "avi.png";
            break;
        case "bat":
            $type = "Batch file";
            $image = "bat.png";
            break;
        case "css":
            $type = "Cascading Style Sheet";
            $image = "txt.png";
            break;
        case "exe":
            $type = "Executable file";
            $image = "exe.png";
            break;
        case "fla":
            $type = "Flash file";
            $image = "fla.png";
            break;
        case "gif":
            $type = "GIF Image";
            $image = "gif.png";
            break;
        case "html":
            $type = "HTML file";
            $image = "html.png";
            break;
        case "htm":
            $type = "HTM file";
            $image = "html.png";
            break;
        case "jpg":
            $type = "JPEG Image";
            $image = "jpg.png";
            break;
        case "mp3":
            $type = "Music File";
            $image = "mp3.png";
            break;
        case "msg":
            $type = "Email message";
            $image = "msg.png";
            break;
        case "pdf":
            $type = "PDF file";
            $image = "pdf.png";
            break;
        case "psd":
            $type = "Photoshop file";
            $image = "psd.png";
            break;
        case "php":
            $type = "PHP file";
            $image = "php.png";
            break;
        case "ppt":
            $type = "PowerPoint presentation";
            $image = "ppt.png";
            break;
        case "pptx":
            $type = "PowerPoint presentation";
            $image = "ppt.png";
            break;
        case "swf":
            $type = "SWF Flash file";
            $image = "swf.png";
            break;
        case "txt":
            $type = "Text file";
            $image = "txt.png";
            break;
        case "csv":
            $type = "CSV file";
            $image = "txt.png";
            break;

        case "wma":
            $type = "Windows Media Audio";
            $image = "wma.png";
            break;
        case "xls":
            $type = "Excel file";
            $image = "xls.jpg";
            break;
        case "xlsx":
            $type = "Excel file";
            $image = "xls.jpg";
            break;
        case "zip":
            $type = "Zip file";
            $image = "zip.png";
            break;
        case "7zip":
            $type = "Zip file";
            $image = "zip.png";
            break;
        case "zip":
            $type = "Zip file";
            $image = "zip.png";
        case "7z":
            $type = "7Zip file";
            $image = "rar.png";
            break;
        case "doc":
            $type = "Word document";
            $image = "doc.png";
            break;
        case "docx":
            $type = "Word document";
            $image = "doc.png";
            break;
        case "docs":
            $type = "Word document";
            $image = "doc.png";
        case "rar":
            $type = "Rar file";
            $image = "rar.png";
        //--- New Here---//
        default:
            $type = "Unknown file";
            $image = "unknown.jpg";
        }
        return $type . "?" . $image;
    }
}
?>

Then you Create FileTable.php in which all of your files and folders will be displayed and you will be able to access them and download selected files (Only files not folders) + (I have added simple filtering)

    <?php 
$cleanPath = $target;

/**
 * CURRENT DIRECTORY LOCATION DISPLAY FIX
 */
switch (strlen($cleanPath)) {
    case 1:
        $cleanPath[0] = " ";
        break;

    case 2:
        if($cleanPath[0] == "\\" && $cleanPath[1] == "/"){
            $cleanPath[0] = " ";
            $cleanPath[1] = " ";
            $cleanPath[2] = " ";
            break;
        }else {
            $cleanPath[0] = " ";
            break;
        }
    default:
        $cleanPath[0] = " ";
        break;
}

/**
 * HERE WRITE ALL FILES YOU WANT FileReader TO IGNORE
 * - WRITE file + its extension
 * - FOR DIRECTORY WRITE THE NAME OF THE DIRECTORY TO IGNORE
 */
$filesToIgnore = [
    'index.php',
    'index.css',
    'index.html',
    'Restricted',
    'PUT YOUR FILES HERE.txt'
];
?>

<?php if(strlen($target) != 0): ?>
    <p class="CurrentFolderLocation"><?= $cleanPath; ?></p>
<?php else: ?>
    <p class="CurrentFolderLocation"></p>
<?php endif ?>

<table class="FileTable">
    <div class="InputArea">
        <input type="text" id="filterInput" onkeyup="filterTable()" placeholder="Name of the file to search for...">
    </div>
    <thead class="TableHead">
        <tr>
            <th>
                <a class="ReturnImg"  href="?path=<?= urlencode($reader->removeRootFromPath(dirname($target))); ?>">
                    <img src= "../Components/icons/levelup.png" alt="level up"/>
                </a> 
            </th>
            <th>File name</th>
            <th>File size</th>
            <th>File type</th>
            <th>Last file modification date</th>
        </tr>
        
    </thead>
    <tbody id="tableBody" class="TableBody">            
        <?php if ($results = $reader->readDirectory($target)): ?>
            <?php foreach($results as $result): ?>
                <?php
                    $currentFileToCheck = explode("\\",$result);
                    $currentFileToCheck = $currentFileToCheck[array_key_last($currentFileToCheck)];
                ?>
                <?php if(!in_array($currentFileToCheck,$filesToIgnore)): ?>
                    <tr>
                        <?php

                        // Make the full path user friendly by removing the root directory.
                        $user_friendly = $reader->removeRootFromPath($result->getFileInfo());

                        //File information
                        $fileName = pathinfo($result,PATHINFO_BASENAME);
                        $fileInfo = explode("?",($reader->returnFileExtensionAndImage(pathinfo($result,PATHINFO_EXTENSION))),2);
                        $fileExtension = $fileInfo[0];
                        $fileIcon = $iconsPath . $fileInfo[1];
                        $fileDateModified = explode(" ",date("F d.Y - H:i:s",filemtime($result)),4);
                        $fileDateModified = implode(" ",$fileDateModified);

                        $type = $result->getType();
                            if($type !== 'dir'){
                                $fileSize = $reader->humanFilesize(filesize($result));
                            }
                        ?>
    
                        <?php if($type === 'dir'): ?>
                            <td><img class="FileImage" src="../Components/icons/folder.jpg"></td>
                            <td>
                                <a href="?path=<?= urlencode($user_friendly); ?>"><?= $fileName; ?></a>
                            </td>
                            <td></td>
                            <td></td>
                            <td></td>
                        <?php else: ?>  
                            <td><img class="FileImage" src=<?= $fileIcon; ?> alt="Ikonka souboru"></td>

                            <?php if(pathinfo($result,PATHINFO_EXTENSION) == "pdf"): ?>
                                <td><a target="_blank" href="./<?= $user_friendly; ?>"><?= $fileName; ?></a></td>
                            <?php else: ?>
                                <td><a download href="./<?= $directoryToScan . "/" . $user_friendly; ?>"><?= $fileName; ?></a></td>
                            <?php endif ?>

                            <td><?= $fileSize; ?></td>
                            <td><?= $fileExtension; ?></td>
                            <td><?= $fileDateModified; ?></td>

                        <?php endif ?>
                    </tr>
                <?php endif ?>
            <?php endforeach ?>
        <?php else: ?>
            <tr>
                <td></td>
                <td>Directory/File doesn't exist</td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        <?php endif ?>
    </tbody>
</table>

<script>
    function filterTable() {
    // Declare variables
    let input = document.getElementById("filterInput"),
        filter = input.value.toUpperCase(),
        table = document.getElementById("tableBody"),
        tr = table.getElementsByTagName("tr"),
        td, 
        i, 
        txtValue;


    // Loop through all table rows, and hide those who don't match the search query
    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[1];
            if (td) {
                txtValue = td.textContent || td.innerText;
                if (txtValue.toUpperCase().indexOf(filter) > -1) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    }
</script>

And at last you will create index.php where you will connect this together

    <?php

$path = $_SERVER['DOCUMENT_ROOT']; // Get Root path of your file system

$componentPath = $path . "/Components/";
$componentFileReader = $componentPath . "FileReader.php";
$componentFileTable = $componentPath . "FileTable.php";

$iconsPath = "/Components/icons/";
$cssStyle = "./Components/index.css";

include($componentFileReader);
$directoryToScan = 'src'; // Relative to current file. Change to your path!
$reader = new FileReader(__DIR__ . DIRECTORY_SEPARATOR . $directoryToScan);
$target = $reader->removeRootFromPath(!empty($_GET['path']) ? $_GET['path'] : '/');

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <link rel="stylesheet" href=<?=$cssStyle; ?>> 
    <title>File browser</title>
    
</head>
<body>

    <main class="PageBody flex-column">
        <?php include($componentFileTable) ?>
    </main>

</body>
</html>

Should you need it -> CODE HERE <- Here is my code on Github with some CSS styling and some icons -> Simply download it and put it in your htdocs folder if you are using Apache



Answered By - Filip Studený
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, January 16, 2022

[FIXED] What is the default order of file elements in Symfony finder?

 January 16, 2022     iterator, php, symfony, symfony-finder     No comments   

Issue

The following code returns different results in two environments (which however were supposed to be as close to one another as possible: the same PHP version, etc.)

The /var/www/html/project/vendor/package/path/to/some/folder directory contains exactly the same set of files in both environments. The files themselves were put there by composer.

use Symfony\Component\Finder\Finder;

// Don't mind this. The real app uses an autoloading mechanism.
require __DIR__ . '/../vendor/symfony/finder/Finder.php';
require __DIR__ . '/../vendor/symfony/finder/SplFileInfo.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/PathFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FilenameFilterIterator.php';
require __DIR__ . '/../vendor/symfony/finder/Iterator/FileTypeFilterIterator.php';

$path = '/var/www/html/project/vendor/package/path/to/some/folder';
$path = Finder::create()->files()->followLinks()->name('/\.(php|inc|hh)$/')->in($path);

$iterator = $path->getIterator();
$iterator->rewind();
$current = $iterator->current();
echo $current->getRelativePathname();

It isn't random. The results are consistent in a single environment. But a different path name is diplayed in either environment. I was able to trace it down to PHP's native: FilterIterator::rewind, but I'm not sure if rewinding is the problem here.


Solution

There is no defined "default" order for the Finder component.

Finder's iterator (Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator) extends on the core \RecursiveDirectoryIterator, which does not define a default order (nor a way to "set" the order). The ordering is thus not guaranteed defined or guaranteed. It is highly system-dependant and file-system dependant, and should not be be relied upon.

If you need a dependable, consistent sort order, just use the appropriate sort*() methods on the Finder instance. This will cause the result to be wrapped on a SortableIterator when you call getIterator(), and get you results ordered in a predictable manner.



Answered By - yivi
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing