longchute

about

Resistor Quiz

11 Oct 2014

This is a simple resistor quiz for both color bands to values and values to color bands. I wrote it because I couldn't find a quiz generator which worked in both directions. All values are in ohms. The list common_values can be altered to change the list of values from which quiz questions are selected. Currently, there are no values in the list for silver and gold third bands (as the list is purloined from toyga), but the code supports them. The quiz only covers the first three bands (four bands and tolerance values aren't implemented). It's not particularly fancy (there is no GUI, but one could easily be added), but it's only meant to refresh my memory after long periods of working on other projects. Tested on Python 2.7.8.

Usage: ./resistor_quiz.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python

import sys
import random

first_bands = {
    0:  'black',
    1:  'brown',
    2:  'red',
    3:  'orange',
    4:  'yellow',
    5:  'green',
    6:  'blue',
    7:  'violet',
    8:  'grey',
    9:  'white'
}

third_band = {
    .01:        'silver',
    .1:         'gold',
    1:          'black',
    10:         'brown',
    100:        'red',
    1000:       'orange',
    10000:      'yellow',
    100000:     'green',
    1000000:    'blue'
}

common_values = [  #   In ohms
    10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82,
    91, 100, 110, 120, 130, 150, 160, 180, 200, 220, 240, 270, 300, 330, 360, 390, 430, 470, 
    510, 560, 620, 680, 750, 820, 910, 1000, 1100, 1200, 1300, 1500, 1600, 1800, 2000, 2200, 
    2400, 2700, 3000, 3300, 3600, 3900, 4300, 4700, 5100, 5600, 6200, 6800, 7500, 8200, 9100, 
    10000, 11000, 12000, 13000, 15000, 16000, 18000, 20000, 22000, 24000, 27000, 30000, 33000,
    36000, 39000, 43000, 47000, 51000, 56000, 62000, 68000, 75000, 82000, 91000, 100000, 
    110000, 120000, 130000, 150000, 160000, 180000, 200000, 220000, 240000, 270000, 300000, 
    330000, 360000, 390000, 430000, 470000, 510000, 560000, 620000, 680000, 750000, 820000, 
    910000, 1000000, 1100000, 1200000, 1300000, 1500000, 1600000, 1800000, 2000000, 2200000, 
    2400000, 2700000, 3000000, 3300000, 3600000, 3900000, 4300000, 4700000, 5100000, 5600000, 
    6200000, 6800000, 7500000, 8200000, 9100000, 10000000, 11000000, 12000000, 13000000, 
    15000000, 16000000, 18000000, 20000000, 22000000, 24000000, 27000000, 30000000, 33000000, 
    36000000, 39000000, 43000000, 47000000, 51000000, 56000000, 62000000, 68000000, 75000000, 
    82000000, 91000000]
common_values = map(float, common_values)

#   Splits a number into digits
def digits(number):
    if (number <= 0):
        print("Value too low.")
        return

    values = []

    while (number > 0):
        values.insert(0, int(number % 10))
        number //= 10

    return values

#   Calculates band colors given resistance in ohms
def color_of(resistor_value):
    #   Dummy check
    if (resistor_value < 0.1):
        print("Value too low.")
        return

    #   Third band
    tb = None

    for tb_value in sorted(third_band.keys(), reverse=True):
        if ((resistor_value / tb_value) < 10.0): continue
        tb = tb_value
        break

    #   First and second bands
    resistor_value /= tb_value
    return([first_bands[value] for value in digits(resistor_value)] + [third_band[tb]])

#   Calculates resistor value given a list of colors
def value_of(resistor_colors):
    values = list()

    #   Find the values for the first and second bands
    for current_color, current_value in resistor_colors[:2]:
        for (value, color) in first_bands.iteritems(): 
            if (color == current_color):
                values.append(value)

    #   Multiply the first two bands' values by the third band's value
    for (value, color) in third_band.iteritems():
        if (color == resistor_colors[2]):
            return int("".join([str(i) for i in values])) * value

def color_to_value():
    correct_answer  = random.choice(common_values)
    question        = " ".join([i for i in color_of(correct_answer)])

    sys.stdout.write("Value of: %s? " % question)
    answer = float(raw_input())

    if (answer == correct_answer): 
        print("Correct!")
        return True
    else: 
        print("Incorrect! It's %.2f ohms." % correct_answer)
        return False

def value_to_color():
    question        = random.choice(common_values)
    correct_answer  = " ".join([i for i in color_of(question)])
    
    sys.stdout.write("Color bands for: %s ohms? " % question)
    answer = raw_input()

    if (answer == correct_answer): 
        print("Correct!")
        return True
    else: 
        print("Incorrect! It's %s." % correct_answer)
        return False   

def resistor_quiz():
    quizzes = [color_to_value, value_to_color]

    while True:
        #   Select quiz
        print("Resistor Quiz")
        print("-------------")
        print("0: color -> value")
        print("1: value -> color")
        sys.stdout.write("\nQuiz type? ")
        quiz_type = int(raw_input())
        sys.stdout.write("Number of questions? ")
        num_questions = int(raw_input())
        print("")

        #   Run quiz
        score = 0.0
        for question in range(0, num_questions):
            if(quizzes[quiz_type]()): score += 1.0

        #   Score quiz
        score_message = "\nScore: %d of %d (%.2f%%)" % (score, num_questions, (score / float(num_questions) * 100.0))
        print(score_message)
        print("-" * len(score_message))

        #   Another quiz?
        sys.stdout.write("Try again (y/n)? ")
        if (raw_input() == "y"): 
            print("")
            continue
        else: break

if (__name__ == '__main__'):
    resistor_quiz()