Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
Anonymous
Not applicable

How to evaluate test results from multiple students?

I have a process that works with a small data set.  But it doesn't scale .... so there must be a better way.  I hope the experts in this group can help.  The data below is a representative subset to demonstrate the use case.  The real data has 1500 rows in the answer key and 500 students.... 

 

I have an table that represents the answer key. 

Steph99_0-1651685188640.png

I have an table that represents the responses received from several students.

Steph99_1-1651685233060.png

What is the best way to develop the pass/fail score for the students?

 

What I did was this:

1) create a query to generate a unique list of students (S1, S2, S3)

2) use a cross join with the AnswerKey Table to generate an ExpandedKey Table  that looks like this  

Steph99_2-1651685381276.png

and

3) do full outer join between the ExpandedKey Table and the Student Answers to achieve this... I can't do a simple join, because the student reponses may have missed answers (i.e. S3 did not answer Q4 or Q5)

Steph99_4-1651685471938.png

 

From here it is easy enough to compare the Answer columns and determine the student's score.

 

BTW - just to clarify, it is not enough for me to simply calculate & report the student score.  I need to give them a report that shows their response and the answer.... so I need to produce a report that looks like this:

Steph99_0-1651756834486.png

 

As I said at the outset, this example works fine... but doesn't scale to serve my environment.  Is there a better way for me to do this so that I don't need to cross join and a full outer join?  Is there some way to loop through and analyze the answers received from S1 and calculate the score, and then analyze the answers from S2 and then S3 etc?

 

Thank you.  I appreciate your guidance.

 

1 ACCEPTED SOLUTION

 

Aah, gotcha. Sorry.

 

Try this instead:

// Call this 'stephAnswers'
let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKjRU0lEyVIrVATKNgMwkCNMYyCwpKk2F8ExAEjmJydkQrimQa2mpFBsLAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [question = _t, answer = _t])
in
    Source

 

// Call this 'stephTest'
let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKjZU0lEqBBGGSrE6ML4RkEhC4hsDiZKi0lQkIROQkpzE5GwkMVMgYWkJETBCM9cIzVwjmLlpiTnFqUhiIIPLMzJLkMVABhsaQE0yRjPZGM1kY1QXxwIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [student = _t, question = _t, answer = _t]),
    addStudentQ = Table.AddColumn(Source, "studentQ", each Text.Combine({[student], [question]}, "-"), type text)
in
    addStudentQ

 

// Call this 'stephRootTable'
let
    Source = Table.Distinct(Table.SelectColumns(stephTest, "student")),
    addPossQuestion = Table.AddColumn(Source, "possQuestion", each stephAnswers[question]),
    expandPossQuestion = Table.ExpandListColumn(addPossQuestion, "possQuestion"),
    addStudentQ = Table.AddColumn(expandPossQuestion, "studentQ", each Text.Combine({[student], [possQuestion]}, "-"), type text),
    chgTypes = Table.TransformColumnTypes(addStudentQ,{{"possQuestion", type text}})
in
    chgTypes

 

Apply all three to your model and relate as follows:

 

stephAnswers[question] > stephRootTable[possQuestion]

stephTest[studentQ] > stephRootTable[studentQ]

BA_Pete_0-1651761053521.png

 

Add a new custom column in stephRootTable as follows:

..score = IF(RELATED(stephTest[answer]) = RELATED(stephAnswers[answer]), 1, 0)

 

Chuck it all in a table as follows:

BA_Pete_1-1651761420628.png

 

This should be super-scalable as you're combining lower-resource functions of Power Query with the power of relationships to avoid costly PQ joins.

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




View solution in original post

9 REPLIES 9
Anonymous
Not applicable

@BA_Pete  - Thank you for sharing the solution... This experience has taught me that I have a lot more to learn.  For the past year or so, I've been creating charts and transforming the data model using the tool presented in the buttons on the ribbon to calculate what I need.  I need to return to my online course and study the section on Measures and Calculated columns and get much deeper knowledge of all the functions that are in M & DAX.  Thanks for sharing the code.  Now all I need to do is modify the table/column names to suite and switch out the source of my data.  You have been a wonderful coach.  I'll reply again again after I have made the modifications and confirmed that the solution scales to meet the data I need to use.  You've been a great assistance and coach.

 

No problem Steph, any time.

Best of luck with your studies 🙂

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




BA_Pete
Super User
Super User

Hi @Anonymous ,

 

Apply both your test table and the correct answers table to your data model.

Relate test[question] to correctAnswers[question].

Add custom column in the test table like this:

 

..score = 
IF(test[answer] = RELATED(correctAnswers[answer]), 1, 0)

 

 

From here you should be able to perform any calculations you want using your new [..score] column.

If you need to do a percentage, then divide by COUNTROWS(correctAnswers), something like this:

 

_scorePct =
DIVIDE(
    SUM(test[..score]),
    COUNTROWS(correctANSWERS),
    0
)

 

 

I get the following output:

BA_Pete_0-1651755551902.png

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




Anonymous
Not applicable

@BA_Pete  - Thanks for the suggestion and the formula.  I've ammended the description of the problem.  calculating the score is not a challenge... it is producing the result that is the challenge.  I need to produce a report for each student that shows their score vs the answer key.    I will use bursting capabilities to generate each report, but I need the report to look something like this.

Steph99_1-1651756717539.png

 

BTW Thanks for the suggestion regarding the relate capability.  I see that I have much to learn regarding DAX.

 

Stephanie

 

Aah, gotcha. Sorry.

 

Try this instead:

// Call this 'stephAnswers'
let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKjRU0lEyVIrVATKNgMwkCNMYyCwpKk2F8ExAEjmJydkQrimQa2mpFBsLAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [question = _t, answer = _t])
in
    Source

 

// Call this 'stephTest'
let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WKjZU0lEqBBGGSrE6ML4RkEhC4hsDiZKi0lQkIROQkpzE5GwkMVMgYWkJETBCM9cIzVwjmLlpiTnFqUhiIIPLMzJLkMVABhsaQE0yRjPZGM1kY1QXxwIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [student = _t, question = _t, answer = _t]),
    addStudentQ = Table.AddColumn(Source, "studentQ", each Text.Combine({[student], [question]}, "-"), type text)
in
    addStudentQ

 

// Call this 'stephRootTable'
let
    Source = Table.Distinct(Table.SelectColumns(stephTest, "student")),
    addPossQuestion = Table.AddColumn(Source, "possQuestion", each stephAnswers[question]),
    expandPossQuestion = Table.ExpandListColumn(addPossQuestion, "possQuestion"),
    addStudentQ = Table.AddColumn(expandPossQuestion, "studentQ", each Text.Combine({[student], [possQuestion]}, "-"), type text),
    chgTypes = Table.TransformColumnTypes(addStudentQ,{{"possQuestion", type text}})
in
    chgTypes

 

Apply all three to your model and relate as follows:

 

stephAnswers[question] > stephRootTable[possQuestion]

stephTest[studentQ] > stephRootTable[studentQ]

BA_Pete_0-1651761053521.png

 

Add a new custom column in stephRootTable as follows:

..score = IF(RELATED(stephTest[answer]) = RELATED(stephAnswers[answer]), 1, 0)

 

Chuck it all in a table as follows:

BA_Pete_1-1651761420628.png

 

This should be super-scalable as you're combining lower-resource functions of Power Query with the power of relationships to avoid costly PQ joins.

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




Anonymous
Not applicable

@BA_Pete - quick question... what is the long multicharater text after after FromText?  Where does this come from?  Why the reference to a Json document? What is being decompressed?  all the data is coming from spreadsheets... Thx.

FromText("i45WKjZU0lEqBBGGSrE6ML4RkEhC4hsDiZKi0lQkIROQkpzE5GwkMVMgYWkJETBCM9cIzVwjmLlpiTnFqUhiIIPLMzJLkMVABhsaQE0yRjPZGM1kY1QXxwIA",

 

Hi Steph,

 

This is just how Power Query represents data that has been created using the 'Enter Data' function.

It stores it as a text representation of a JSON binary so that it's very quick and easy to share built tables just by copying and pasting the M code. In scenarios such as this, where I want to share a complete, working, solution with someone on a forum, it allows me to send a complete table in text form, and allows you to just paste it wholesale into a blank query using Advanced Editor and have a complete table ready to use.

Once you've pasted all the tables into PQ at your end, named them as suggested, and tested that my proposed solution works as required, you would then swap out the whole Source step from these queries and replace it with the Source step(s) that point to your actual data.

 

For example, if I paste the whole of the first code segment into Advanced Editor, like this:

BA_Pete_0-1651824519106.png

 

When I hit 'Done', I get this, a fully-formed and formatted table of example data:

BA_Pete_1-1651824592775.png

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




ddpl
Solution Sage
Solution Sage

Hi,

 

please try this,

 

Step1:

Merge both the table as per in the basis Key column as Answers

 

VipulGadhiya_0-1651737424279.png

 

 

Step2: Then create conditional column

 

VipulGadhiya_1-1651737445021.png

 

 

Step3: Then Group by Student name

 

VipulGadhiya_2-1651737459160.pngVipulGadhiya_3-1651737466287.png

 

 

Now you can create custom column for %

 

VipulGadhiya_4-1651737477091.pngVipulGadhiya_5-1651737483895.png

And same you can add one more custom column stating Pass or Fail

 

 

Anonymous
Not applicable

Vipul - Thanks for the suggestion works fine to calculate the score... BTW, Thanks for introducing me to the group by command.  That is awesome and I will used it for other applications.

 

My challenge is that it is not enough to calculate a score.  I need to show the results and the comparison... thus I can't do an inner join, I need to do an outer join..... 

I need to show this is my final report to the student 

Steph99_0-1651756045796.png

With the inner join all I get it this

Steph99_1-1651756075145.png

Thanks for the tip... but I'll need to try something else.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors
Top Kudoed Authors