My code components works correctly in the background but does not show the result I want on builder. What do I do?r

OS (e.g. Win10): Windows 11
PsychoPy version (e.g. 1.84.x): Psychopy Builder (v2024.1.5)
Standard Standalone? (y/n) If not then what?: Yes

What are you trying to achieve?:
In my experiment the participant must click on a point on a slider scale , where there is a topic on each end. Wherever they click , the topic that is closest (for some conditions) or farthest (for one condition) on the scale get recorded for use for a later part of the experiment. the slider goes from -3 to +3, and for conditions C and HI positive ratings should result in ChoiceB and negative ratings in ChoiceA, while in condition LI it should be reversed. This all happens in the Choose_Topic loop (see screenshot below)

After being recorded on an excel sheet, the topics are presented in a text variable in Fact_Trials loop in the same experiment. Here is a picture for clearer understanding

What did you try to make it work?:
Under the Choose_Topic loop, I used this code for the coding component that needs to be done each frame

if Type == "C":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceB
    else:
        Answer=ChoiceA
elif Type == "HI":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceB
    else:
        Answer=ChoiceA
elif Type == "LI":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceA
    else:
        Answer=ChoiceB

and this code at the end of the routine in the Choose_Topic loop to save it on the excel file to be used in the Fact_trials loop (i have no code at the begining of the routine)

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

# Assuming you have collected some data
Answer1 = Answer  # Replace this with the actual collected answer

# Prepare the new data to append
New_data = pd.DataFrame({'Answer': [Answer1]})

# Load existing Excel data
#file_path = r'C:\Program Files\PsychoPy\Agency\AgencyTrial2.xlsx'
file_path = r"C:\Users\Ghalia\Documents\AgencyDraft\AgencyTrial2.xlsx"
sheet_name = 'Sheet1'

# Read the existing data
try:
    df = pd.read_excel(file_path, sheet_name=sheet_name)
except FileNotFoundError:
    df = pd.DataFrame()  # If the file does not exist, create an empty DataFrame

# Append the new data to the existing DataFrame at the end
df = pd.concat([df, New_data], ignore_index=True)

# Write the updated DataFrame back to Excel
df.to_excel(file_path, sheet_name=sheet_name, index=False)

# Load the workbook and select the sheet
wb = load_workbook(file_path)
sheet = wb[sheet_name]

# Define source and destination ranges
source_range = sheet['F8:F13']
dest_range_start_row = 2
dest_range_start_col = 6

# Copy the values from source range to destination range
for i, row in enumerate(source_range):
    for j, cell in enumerate(row):
        dest_cell = sheet.cell(row=dest_range_start_row + i, column=dest_range_start_col + j)
        dest_cell.value = cell.value

# Optional: Copy row heights and column widths manually if needed
# Example: copying row heights (Note: Adjust if your rows are different)
for i, row in enumerate(source_range):
    src_row_height = sheet.row_dimensions[row[0].row].height
    sheet.row_dimensions[dest_range_start_row + i].height = src_row_height

# Example: copying column widths (Note: Adjust if your columns are different)
for j in range(len(source_range[0])):
    src_col_width = sheet.column_dimensions[source_range[0][j].column_letter].width
    sheet.column_dimensions[sheet.cell(row=dest_range_start_row, column=dest_range_start_col + j).column_letter].width = src_col_width

# Save the workbook
wb.save(file_path)

print("Data successfully added to Excel sheet and formatting updated.")

What specifically went wrong when you tried that?:
the code works and records the topics I need for the fact_trials loop (as seen below):

However, when I try to pilot the experiment on builder, it only presents the last topic (in this case cultural appropriation) 6 times instead of presenting the 6 topics sequentially ( I have set the loop to only show the first 6 rows of the excel sheet)

I am not sure if this is due to an error in my code or something on this version of the builder, given that the experiment works on an older version of psychopy (don’t remember which version) on an old windows 10 computer. Please help?

(Also the end routine code does not want to be converted to JavaScript from python on builder. I think it needs to be in JS in order to run online on pavlovia. How can I make it work?)

If you want this to work online then you need to avoid pandas and other Python libraries.

If your second loop is presenting the same row six times, please could you show your loop?

@wakecarter here is the loop for Choose_Topic:
Screenshot 2024-08-15 132105

and here is the loop for Fact_trials:
Screenshot 2024-08-15 132119

If i need to avoid pandas and other libraries for the code to work online, what do i need to do to make sure the code is doing what i intend it to do?

It depends what you want to do, but I would start with my code snippet for trial handlers.

For that second loop why are you setting the use rows to 0:6 when you could tidy up the spreadsheet and show the whole thing?

Thank you for the Component snippets. MY PC is currently updating so I will test them later and let you know if I succeed n making them work.

The reason why I am making psychopy use row 0:6 is because when the data from teh Choose-Topic loop is recorded, it is recorded 6 rows below, and I need the data 6 rows above in order to present it in my next loop

Are you trying to write information into the CSV file for a later loop? If so, then I don’t think you can do that online. It’s better to store information into a list or dictionary.

If that is the case then how do I go about doing it?

As Wake mentioned, storing the trials info as a temporary file, will not work online. There is a way, however, of feeding custom trial info directly into a loop. You can read about it here:

https://workshops.psychopy.org/3days/day3/builder_parallel/customRandomisation.html

This is not a copy/paste solution to your specific problem. This only hints to the direction you may want to follow.

Things you will need to do:

  • Store all relevant values of the initial Choose_Topic routine in a dictionary.
  • For each iteration of the ChooseTopics_trials loop, add the dictionary to a list.

Then, follow the (relevant) instructions of the link above. You will have to modify the code to fit your specific case, however.

thank you for all the information @wakecarter and @umb so far! I am not really good with code (this is my first time coding is psychopy actually). However, i am not sure if I understood how to do lists and dictionaries properly. Here is what I have so far:

in the ChooseTopics_trials loop, for the code component at the beginning of the routine I put this code:

# Initialize an empty dictionary to store ratings
Answer = {}

and for each frame I put:

if Type == "C":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceB
    else:
        Answer=ChoiceA
elif Type == "HI":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceB
    else:
        Answer=ChoiceA
elif Type == "LI":
    if Choose_slider.getRating() is not None and Choose_slider.getRating() > 4:
        Answer=ChoiceA
    else:
        Answer=ChoiceB

and for end routine I put this:

# Convert dictionary values to a list
ratings_list = list(Answer)

print(ratings_list)

I am not sure if i put the correct code in the correct placem,ents, and i am not sure how to refrence the list created in the Choose_Topic loop in the following loop (Fact_trials loop). Any recommendations?

solution is found here