Skip to content

Conversation

@frodo-repo
Copy link
Contributor

@frodo-repo frodo-repo commented Feb 20, 2025

.

Summary by CodeRabbit

  • New Features

    • Added input validation: non-integer inputs raise TypeError; negative integers raise ValueError.
  • Refactor

    • Reworked Fibonacci logic for performance with memoized and iterative implementations; removed inline example/test calls.
    • Note: a prior implementation now coexists with a later one, causing the later definition to take precedence and potentially produce inconsistent behavior.
  • Tests

    • Added unit tests covering base cases, typical indices, and validation errors.

@frodo-repo frodo-repo changed the title improve fibonacchi examples improve fibonacchi examples [change in title] Feb 20, 2025
@frodo-repo frodo-repo closed this Feb 24, 2025
@frodo-repo frodo-repo reopened this Feb 24, 2025
frodo-repo and others added 2 commits February 24, 2025 13:30
Co-authored-by: qodo-merge-pro[bot] <151058649+qodo-merge-pro[bot]@users.noreply.github.com>
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
coderabbitai[bot]

This comment was marked as off-topic.

@coderabbit-test coderabbit-test deleted a comment from qodo-merge-pro bot Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from qodo-merge-pro bot Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from qodo-merge-pro bot Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from qodo-merge-pro bot Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from coderabbitai bot Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@coderabbit-test coderabbit-test deleted a comment from frodo-repo Aug 6, 2025
@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Code Review: Fibonacci Implementation Improvements

👍 Well Done
Improved Algorithm Efficiency

Replaced recursive implementation with iterative approach, reducing time complexity from O(2^n) to O(n) and eliminating stack overflow risk

Proper Input Validation

Added type and value checking with appropriate error handling for non-integer and negative inputs

Comprehensive Test Coverage

Added test suite covering base cases, positive values, and input validation error scenarios

📌 Files Processed
  • main.py
  • test.py
📝 Additional Comments
main.py (2)
Variable Naming Could Be More Descriptive

The variable names 'prev1', 'prev2', and 'curr' could be more descriptive to improve code readability and self-documentation. More meaningful names would make the algorithm easier to understand at a glance.

current_fib = 1
previous_fib = 0
for i in range(2, n + 1):
    next_fib = current_fib + previous_fib
    previous_fib = current_fib
    current_fib = next_fib
return current_fib

Standards:

  • Clean Code
  • Naming Conventions
Missing Function Documentation

The function lacks a proper docstring explaining its purpose, parameters, return values, and exceptions. Adding documentation would improve code maintainability and help users understand how to use the function correctly.

def nth_fibonacci(n):
    """
    Calculate the nth Fibonacci number using an iterative approach.
    
    Args:
        n (int): A non-negative integer representing the position in the Fibonacci sequence
        
    Returns:
        int: The nth Fibonacci number
        
    Raises:
        TypeError: If n is not an integer
        ValueError: If n is negative
    """
    if not isinstance(n, int):
        raise TypeError("Input must be an integer")

Standards:

  • Documentation Standards
  • Code Readability
test.py (1)
Test Coverage Could Include Performance Testing

While the test suite covers functional correctness, it doesn't include performance testing for larger inputs to verify the efficiency improvement of the iterative approach over the recursive one.

def test_large_input_performance(self):
    # This should execute quickly with the iterative implementation
    # but would timeout with a recursive implementation
    n = 35
    result = nth_fibonacci(n)
    self.assertEqual(result, 9227465)

Standards:

  • Test Coverage
  • Performance Testing

main.py Outdated
Comment on lines 91 to 93
n = 5
result = nth_fibonacci(n)
print(result)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Execution Code Not Protected by Module Guard

The execution code at the end of the file is not protected by an if name == "main": guard. This means the code will execute when imported as a module, causing unintended side effects and violating Python best practices.

Suggested change
n = 5
result = nth_fibonacci(n)
print(result)
if __name__ == "__main__":
n = 5
result = nth_fibonacci(n)
print(result)
Standards
  • Python Best Practices
  • Module Design

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

PR already reviewed at the latest commit: 396c569.
Please try again with new changes.

Co-authored-by: refacto-test[bot] <217047508+refacto-test[bot]@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
main.py (1)

1-16: Remove obsolete memoized helper and wrapper after consolidation

After adopting a single iterative nth_fibonacci, this helper and wrapper become dead code and add maintenance burden. The recursive approach also risks recursion depth for large n.

Apply these diffs to remove them:

-# Function to calculate the nth Fibonacci number using memoization
-def nth_fibonacci_util(n, memo):
-
-    # Base case: if n is 0 or 1, return n
-    if n <= 1:
-        return n
-
-    # Check if the result is already in the memo table
-    if memo[n] != -1:
-        return memo[n]
-
-    # Recursive case: calculate Fibonacci number
-    # and store it in memo
-    memo[n] = nth_fibonacci_util(n - 1, memo) + nth_fibonacci_util(n - 2, memo)
-
-    return memo[n]
-# Wrapper function that handles both initialization
-# and Fibonacci calculation
-def nth_fibonacci(n):
-
-    # Create a memoization table and initialize with -1
-    memo = [-1] * (n + 1)
-
-    # Call the utility function
-    return nth_fibonacci_util(n, memo)

Also applies to: 19-27

♻️ Duplicate comments (1)
main.py (1)

37-55: Duplicate function definition; consolidate to a single, validated O(1) implementation

This second nth_fibonacci definition shadows the earlier one, making the memoized version dead code and causing inconsistent behavior for negative inputs (e.g., returns a negative number). Consolidate to a single function with input validation and O(1) space.

Apply this diff to replace the duplicate with a single, validated, O(1) iterative implementation:

-def nth_fibonacci(n):
-  
-    # Handle the edge cases
-    if n <= 1:
-        return n
-
-    # Create a list to store Fibonacci numbers
-    dp = [0] * (n + 1)
-
-    # Initialize the first two Fibonacci numbers
-    dp[0] = 0
-    dp[1] = 1
-
-    # Fill the list iteratively
-    for i in range(2, n + 1):
-        dp[i] = dp[i - 1] + dp[i - 2]
-
-    # Return the nth Fibonacci number
-    return dp[n]
+def nth_fibonacci(n: int) -> int:
+    """Return the n-th Fibonacci number (0-indexed).
+
+    Raises:
+        TypeError: if n is not an integer.
+        ValueError: if n is negative.
+    """
+    if not isinstance(n, int):
+        raise TypeError("n must be an integer")
+    if n < 0:
+        raise ValueError("n must be non-negative")
+    if n <= 1:
+        return n
+    prev, curr = 0, 1
+    for _ in range(2, n + 1):
+        prev, curr = curr, prev + curr
+    return curr
🧹 Nitpick comments (1)
main.py (1)

57-58: Remove leftover review-artifact comment

Stray comment “Remove lines 57-59 entirely” appears to be a review artifact and should be removed.

-# Remove lines 57-59 entirely
-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 396c569 and 8554325.

📒 Files selected for processing (1)
  • main.py (1 hunks)
🔇 Additional comments (1)
main.py (1)

30-33: Module guard is correctly used

Good use of if name == "main": to prevent side effects on import.

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

📌 Files Processed
  • test.py
  • main.py

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

No review comments were generated during this review iteration of the PR.

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

PR already reviewed at the latest commit: 8554325.
Please try again with new changes.

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (2)
main.py (2)

1-17: Remove memoized helper and wrapper to eliminate duplication and shadowing.

You currently define nth_fibonacci twice. The later definition shadows the earlier wrapper, and the mid-file __main__ block calls the earlier (buggy) version. Drop the memoized path to avoid confusion and one version drifting from the other.

Proposed removal:

-# Function to calculate the nth Fibonacci number using memoization
-def nth_fibonacci_util(n, memo):
-
-    # Base case: if n is 0 or 1, return n
-    if n <= 1:
-        return n
-
-    # Check if the result is already in the memo table
-    if memo[n] != -1:
-        return memo[n]
-
-    # Recursive case: calculate Fibonacci number
-    # and store it in memo
-    memo[n] = nth_fibonacci_util(n - 1, memo) + nth_fibonacci_util(n - 2, memo)
-
-    return memo[n]
-
-
-# Wrapper function that handles both initialization
-# and Fibonacci calculation
-def nth_fibonacci(n):
-
-    # Create a memoization table and initialize with -1
-    memo = [-1] * (n + 1)
-
-    # Call the utility function
-    return nth_fibonacci_util(n, memo)

Also applies to: 19-28


30-33: Move the module guard to the end of the file.

Placed mid-file, it invokes the earlier (now-removed/buggy) definition before the final version is defined. Move it after the final nth_fibonacci definition.

Remove here:

-if __name__ == "__main__":
-    n = 5
-    result = nth_fibonacci(n)
-    print(result)

Then add at end of file:

if __name__ == "__main__":
    n = 5
    print(nth_fibonacci(n))
♻️ Duplicate comments (1)
main.py (1)

37-41: Revisit input validation only if tests require it.

Previous reviews already suggested type/non-negative checks. If your tests or consumer code expect these, add them; otherwise, you can skip per your earlier stance.

If needed, insert:

 def nth_fibonacci(n):
+    if not isinstance(n, int):
+        raise TypeError("n must be an integer")
+    if n < 0:
+        raise ValueError("n must be non-negative")
     if n <= 1:
         return n

To confirm whether tests rely on this behavior, run:

#!/bin/bash
# Find tests and expectations around nth_fibonacci
fd -t f -e py | xargs rg -n "nth_fibonacci\("
rg -n "assertRaises\(.+(TypeError|ValueError).+nth_fibonacci" -A2 -B2
🧹 Nitpick comments (2)
main.py (2)

37-55: Consolidate to a single, faster O(1)-space iterative implementation.

The current iterative version allocates O(n) space. You can compute Fibonacci in O(1) space and keep only this single definition.

Apply:

-def nth_fibonacci(n):
-  
-    # Handle the edge cases
-    if n <= 1:
-        return n
-
-    # Create a list to store Fibonacci numbers
-    dp = [0] * (n + 1)
-
-    # Initialize the first two Fibonacci numbers
-    dp[0] = 0
-    dp[1] = 1
-
-    # Fill the list iteratively
-    for i in range(2, n + 1):
-        dp[i] = dp[i - 1] + dp[i - 2]
-
-    # Return the nth Fibonacci number
-    return dp[n]
+def nth_fibonacci(n):
+    if n <= 1:
+        return n
+    a, b = 0, 1
+    for _ in range(2, n + 1):
+        a, b = b, a + b
+    return b

57-58: Remove stray reviewer note left in source.

This meta-comment should not be committed.

-# Remove lines 57-59 entirely
-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8554325 and 744f1c1.

📒 Files selected for processing (1)
  • main.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.12.2)
main.py

6-6: Undefined name m

(F821)

# Base case: if n is 0 or 1, return n
if n <= 1:
return n
return m
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix NameError in base case: use n, not m.

Ruff correctly flags m as undefined. This will raise at runtime and break the script under the module guard.

Apply this fix:

-        return m
+        return n
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return m
return n
🧰 Tools
🪛 Ruff (0.12.2)

6-6: Undefined name m

(F821)

🤖 Prompt for AI Agents
In main.py around line 6, the base-case return uses an undefined variable `m`;
replace `m` with the correct parameter `n` so the function returns the intended
value and avoids the NameError at runtime.

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Code Review: Fibonacci Implementation and Testing

👍 Well Done
Proper Unit Test Structure

Added dedicated test file with comprehensive test cases for different Fibonacci scenarios

Removal of Inefficient Recursive Implementation

Eliminated the exponential time complexity recursive approach in favor of the more efficient memoized solution

📌 Files Processed
  • main.py
  • test.py
📝 Additional Comments
main.py (2)
Missing Function Documentation

Functions lack docstrings explaining their purpose, parameters, and return values. This reduces code maintainability and makes it harder for other developers to understand the code.

def nth_fibonacci(n):
    """
    Calculate the nth Fibonacci number.
    
    Args:
        n: A non-negative integer
    
    Returns:
        The nth number in the Fibonacci sequence
    
    Raises:
        TypeError: If n is not an integer
        ValueError: If n is negative
    """
    if not isinstance(n, int):
        raise TypeError("Input must be an integer")
    if n < 0:
        raise ValueError("Input must be non-negative")
    return nth_fibonacci_util(n)

Standards:

  • PEP 257 - Docstring Conventions
Mutable Default Argument in Memoization Function

Using a mutable default argument (empty dict) for memoization can cause unexpected behavior as the memo dictionary persists between function calls. This could lead to memory leaks in long-running applications.

def nth_fibonacci_util(n, memo=None):
    if memo is None:
        memo = {}
    if n in memo:
        return memo[n]

Standards:

  • Python Mutable Default Arguments Best Practice
test.py (1)
Missing Performance Test for Large Fibonacci Numbers

The test suite only verifies small Fibonacci numbers but doesn't test the efficiency of the memoized implementation with larger values, which was the main reason for removing the recursive implementation.

def test_fibonacci_large_value(self):
    # This would be very slow with the recursive implementation
    # but should be fast with memoization
    self.assertEqual(nth_fibonacci(35), 9227465)

Standards:

  • Performance Testing Best Practices

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

PR already reviewed at the latest commit: 744f1c1.
Please try again with new changes.

@arvi18
Copy link

arvi18 commented Aug 12, 2025

/refacto-test

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
main.py (1)

41-59: Remove duplicate nth_fibonacci definition
The second implementation at lines 41–59 shadows the validated version (with type/non-negative checks) above and causes tests to fail. Please remove it so only the public, validated nth_fibonacci remains.

• Location to update:
main.py, lines 41–59

Apply this diff:

-def nth_fibonacci(n):
-  
-    # Handle the edge cases
-    if n <= 1:
-        return n
-
-    # Create a list to store Fibonacci numbers
-    dp = [0] * (n + 1)
-
-    # Initialize the first two Fibonacci numbers
-    dp[0] = 0
-    dp[1] = 1
-
-    # Fill the list iteratively
-    for i in range(2, n + 1):
-        dp[i] = dp[i - 1] + dp[i - 2]
-
-    # Return the nth Fibonacci number
-    return dp[n]
+# Removed duplicate nth_fibonacci; use the validated version above

Optionally, if you’d like to keep an iterative reference internally without exposing it publicly, add:

def _nth_fibonacci_iter(n: int) -> int:
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a
♻️ Duplicate comments (1)
main.py (1)

6-6: Fix NameError in base case: return n, not m.

This will raise at runtime and is flagged by Ruff. Replace m with n.

Apply this diff:

-        return m
+        return n
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 744f1c1 and 06b510c.

📒 Files selected for processing (1)
  • main.py (3 hunks)
🧰 Additional context used
🪛 Ruff (0.12.2)
main.py

6-6: Undefined name m

(F821)

🔇 Additional comments (1)
main.py (1)

20-32: Docstring and input validation look good.

Clear contract and explicit errors for bad input types/values.

Comment on lines +33 to +37
if not isinstance(n, int):
raise TypeError("Input must be an integer")
if n < 0:
raise ValueError("Input must be non-negative")
return nth_fibonacci_util(n)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect helper invocation and missing memo initialization.

nth_fibonacci_util requires a memo parameter. As written, this will fail with a missing-argument TypeError.

Apply this diff:

-    return nth_fibonacci_util(n)
+    # Use memoization helper
+    memo = [-1] * (n + 1)
+    return nth_fibonacci_util(n, memo)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not isinstance(n, int):
raise TypeError("Input must be an integer")
if n < 0:
raise ValueError("Input must be non-negative")
return nth_fibonacci_util(n)
if not isinstance(n, int):
raise TypeError("Input must be an integer")
if n < 0:
raise ValueError("Input must be non-negative")
# Use memoization helper
memo = [-1] * (n + 1)
return nth_fibonacci_util(n, memo)
🤖 Prompt for AI Agents
In main.py around lines 33 to 37, the call to nth_fibonacci_util omits its
required memo argument causing a TypeError and there is no memo initialized; add
a memo (e.g., an empty dict) and pass it into nth_fibonacci_util (for example
create memo = {} after validating n and then return nth_fibonacci_util(n, memo))
so the helper has the memo parameter it expects.

Comment on lines +61 to +62
# Remove lines 57-59 entirely

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove stray review artifact from source.

The line “Remove lines 57-59 entirely” appears to be a leftover review note and should not be in code.

Apply this diff:

-# Remove lines 57-59 entirely
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Remove lines 57-59 entirely
🤖 Prompt for AI Agents
In main.py around lines 61-62, remove the stray review artifact line "Remove
lines 57-59 entirely" from the source; delete that exact text so the file
contains only intended code/comments and then save the file (run linter/tests to
confirm no syntax remains).

@refacto-test
Copy link

refacto-test bot commented Aug 12, 2025

Code Review: Fibonacci Implementation

👍 Well Done
Comprehensive Input Validation

Added proper type checking and value constraints for the Fibonacci function, preventing invalid inputs

Test Suite Implementation

Created a well-structured test file with coverage for base cases, positive values, and input validation

📌 Files Processed
  • main.py
  • test.py
📝 Additional Comments
main.py (1)
Missing Docstring for Helper Function

The helper function nth_fibonacci_util lacks a docstring explaining its purpose, parameters, and return value, unlike the main function which has proper documentation.

def nth_fibonacci_util(n, memo):
    """
    Helper function to calculate the nth Fibonacci number using memoization.
    
    Args:
        n: A non-negative integer
        memo: Memoization array to store previously calculated values
    
    Returns:
        The nth Fibonacci number
    """

Standards:

  • Documentation Best Practices
test.py (1)
Limited Test Coverage for Large Fibonacci Numbers

The test coverage only goes up to n=10, which doesn't verify that the memoization is working effectively for larger values where it would make a significant difference in performance.

def test_positive_values(self):
    self.assertEqual(nth_fibonacci(2), 1)
    self.assertEqual(nth_fibonacci(3), 2)
    self.assertEqual(nth_fibonacci(5), 5)
    self.assertEqual(nth_fibonacci(10), 55)
    self.assertEqual(nth_fibonacci(30), 832040)
    self.assertEqual(nth_fibonacci(35), 9227465)

Standards:

  • Test Coverage Best Practices

Comment on lines +6 to 7
return m

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NameError: Undefined Variable 'm' in Base Case

The base case of nth_fibonacci_util references variable 'm' which is undefined, causing a runtime NameError. This prevents the function from working for any input.

Suggested change
return m
if n <= 1:
return n
Standards
  • Python Variable Scope Rules

raise TypeError("Input must be an integer")
if n < 0:
raise ValueError("Input must be non-negative")
return nth_fibonacci_util(n)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Required Parameter in Function Call

The function nth_fibonacci_util is called with only one argument, but its definition requires two parameters (n, memo). This will cause a runtime error when the function is called.

Suggested change
return nth_fibonacci_util(n)
memo = [-1] * (n + 1)
return nth_fibonacci_util(n, memo)
Standards
  • Function Parameter Consistency

Comment on lines +61 to +62
# Remove lines 57-59 entirely

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented Instruction to Remove Code Remains in Codebase

The comment indicates that lines 57-59 should be removed, but both the comment and the referenced code remain in the codebase. This creates confusion about the intended implementation.

Suggested change
# Remove lines 57-59 entirely
Standards
  • Clean Code Principles

@arvi18 arvi18 closed this Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants