iamcoder
iamcoder

Reputation: 95

How to compare list elements for empty element?

The first input array is the key to the correct answers to an exam, like ["a", "a", "b", "d"]. The second one contains a student's submitted answers.

The two lists are not empty and are of the same length. Return the score for this list of answers, giving +4 for each correct answer, -1 for each incorrect answer, and +0 for each blank answer, represented as an empty string (in C the space character is used). If the score < 0, return 0.

For example:

checkExam(["a", "a", "b", "b"], ["a", "c", "b", "d"]) → 6
checkExam(["a", "a", "c", "b"], ["a", "a", "b",  ""]) → 7

My solution: it is working fine for all other conditions:

def checkExam(arr1,arr2):
    total = 0
    for i,j in zip(arr1, arr2):
        if i == j:
            total += 4
        if i != j:
            total -= 1
        if total < 0:
            return 0
    return total

** Execept this one:

checkExam(["a", "a", "c", "b"], ["a", "a", "b",  ""]) → 7

The problem is that I don't know how to compare ("b") with (" ") (empty element) so it return +0 for blank answer.

**

Upvotes: 1

Views: 153

Answers (4)

user2390182
user2390182

Reputation: 73450

Why do you return from inside the loop when you reach a negative total? Just apply the logic as given:

def check_exam(arr1, arr2):
    total = 0
    for i, j in zip(arr1, arr2):
        if i == j:
            total += 4
        elif j:  # only deduct if j is non-emtpy
            total -= 1  
    return max(total, 0)  # no negative marks

>>> check_exam(["a", "a", "b", "b"], ["a", "c", "b", "d"])
6
>>> check_exam(["a", "a", "c", "b"], ["a", "a", "b",  ""])
7

And if you really want a cryptic one-liner:

def check_exam(arr1, arr2):
    return max(0, sum(4*(i==j) or -bool(j) for i, j in zip(arr1, arr2)))
    # or less cryptic
    return max(0, sum(4 if i==j else -1 for i, j in zip(arr1, arr2) if j))

Upvotes: 1

d-xa
d-xa

Reputation: 524

This will give you what you want

def check_exam(solution, student_submit): 
  scores = [0 if y == "" else 4 if (y==x) else -1 for (x,y) in zip(solution,student_submit)]
  return max(sum(scores),0)

Upvotes: 0

superb rain
superb rain

Reputation: 5520

You could also do it as you would in real life. You know, on paper. Where you wouldn't compare a not-given answer to the expected answer at all. Where you'd skip that entirely.

def check_exam(expect, given):
    total = 0
    for e, g in zip(expect, given):
        if g:
            total += 4 if e == g else -1
    return max(0, total)

One-liner version:

def check_exam(expect, given):
    return max(0, sum(4 if e == g else -1 for e, g in zip(expect, given)))

Other one-liners:

def check_exam(expect, given):
    return max(0, sum((-1, 4)[e == g] for e, g in zip(expect, given)))
def check_exam(expect, given):
    return max(0, sum(f'    {e}'.find(g) for e, g in zip(expect, given)))

The latter one would also handle ' ' correctly (well, like ''):

>>> check_exam(['a', 'a', 'a', 'a'], ['a', 'b', '', ' '])
3

Upvotes: 1

Sachin Rajput
Sachin Rajput

Reputation: 248

try this i think it solves your issue..let me know if it doesn't. even i new to this so any help with code improvement will be great

def check_exam(arr1,arr2):
    total = 0
    for i,j in zip(arr1, arr2):
        if i == j:
            total += 4
        elif j=="": #i have made a change here
            total += 0
        elif i != j:
            total -= 1
    return max(total,0)

Upvotes: 2

Related Questions