Showing posts with label ASA. Show all posts
Showing posts with label ASA. Show all posts

Wednesday, November 30, 2016

grs mobile quiz - qids per chapter

as part of moving to a qids-for-quiz approach (as opposed to embedding falcon, prepware quiz info, etc) with the grs mobile apps:

/Users/smr/current_projects/pws2016/app/controllers/sandbox_controller.rb

  # qids per chapter
  def qidsperc
    quiz_definition = QuizDefinition.find_by_name("Private Pilot, Airplane")
    qids_per_chapter = quiz_definition.qids_per_chapter()
    # qids_per_chapter = JSON.pretty_generate(qids_per_chapter)
    render json: qids_per_chapter
  end


/Users/smr/current_projects/pws2016/app/models/quiz_definition.rb

  def qids_per_chapter
    chapters = self.book.chapters
    dict = {}
    qapc = {}
    chapters.each { |chapter| 
      chapnum = chapter.chapnum
      qids = question_ids_for_chapnum(chapnum)  # N.B. these are shuffled
      dict[chapnum] = qids
      qapc[chapnum] = qids.count
    }
    dict[:qapc] = qapc
    return dict
  end

this script generates the json:
http://localhost:3000/sandbox/qidsperc

which you can then save in a file, e.g. qids_per_chapter.json
and embed into the app bundle.



  1. based on Private Pilot, Airplane
  2. this is based on a quiz definition so categories are taken into account
  3. a qapc data structure is baked in


Thursday, July 7, 2016

ASA notes - pwo fig library and insert sql



after uploading figures and thumbnails to the S3 location, we need to fill the online_figures table with records that describe the figure files.

two approaches considered:
1. create names directly from the fig submodule folder
2. create a copy of the figs folder and normalize the names


##################################################
# 1. create names directly from the fig submodule folder
##################################################
*ended up going with this approach
get filenames from /Users/smr/current_projects/prepware-macos/submodules/figs/
sort using a custom routine
create sql rows from the sorted filenames
create a sql file usable with Sequel Pro's import tool


##################################################
# 2. create a copy of the figs folder and normalize the names
##################################################
see make-working-copy-of-figs.command
these renaming methods might be useful if we decide to normalize figure names.






Friday, July 1, 2016

ASA notes - attempts to use nested test_map_entries with quiz_definition


close but no cigar.
got to a point where the for with the nested TMEs was being submitted without error, but duplicate tme objects are being created.

https://github.com/plataformatec/simple_form/wiki/Nested-Models



/Users/smr/current_projects/pws2016/app/views/quiz_definitions/_form.html.erb
<%= simple_form_for(@quiz_definition) do |qd_fb| %>
  <%= qd_fb.error_notification %>

  <div class="form-inputs">
    <%= qd_fb.input :name %>
    <%= qd_fb.input :category, disabled: true %>
    <p>N.B. currently, this category string is not used to map a quiz defn to categories.
      <code>TODO: replace with category checkboxes</code>
    </p>
    <%= qd_fb.input :minutes_allowed %>
    <%= qd_fb.association :book %>
    <div class="row">
      <div class="col-md-6">
        <table class="table table-bordered table-condensed">
          <tr>
            <th>Chapter</th>
            <th>Available</th>
            <th>Num Questions</th>
          </tr>

          <%= field_set_tag 'Test Map Entry' do %>
            <% @quiz_definition.test_map_entries.each do |test_map_entry| %>
              <%= qd_fb.simple_fields_for "test_map_entries_attributes[]", test_map_entry do |tmf| %>
                <tr>
                  <td><%= test_map_entry.chapnum %></td>
                  <td><%= tmf.input :chapnum %><</td>
                  <td><%= tmf.input :numq %></td>
                </tr>
              <% end %>
            <% end %>
          <% end %>



        </table>
      </div>
    </div>
  </div>

  <div class="form-actions">
    <%= qd_fb.button :submit %>
  </div>
<% end %>



/Users/smr/current_projects/pws2016/app/controllers/quiz_definitions_controller.rb
  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def quiz_definition_params
      params.require(:quiz_definition).permit(:name, :minutes_allowed,
        :test_map_entries_attributes => [:numq, :chapnum]
        )
    end


first attempt (this way doesn't work with strong parameters)
<%= qd_fb.simple_fields_for :test_map_entries do |tme_fb| %>
  <tr>
    <td><%= tme_fb.object.chapnum %></td>
    <td>&nbsp;</td>
    <td><%= tme_fb.input :numq %></td>
  </tr>
  <%#= tme_fb.input :chapnum %>
<% end %>


original form object:
<%= simple_form_for(@quiz_definition) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :category %>
    <%= f.input :minutes_allowed %>
    <%= f.association :book %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>








Saturday, June 25, 2016

ASA notes - add recognition of UAS sku before pw2017 launch




  1. investigate uas sku empty product request
    1. no db yet
    2. no uas codes in the wild before
    3. need to notify user when act code is entered into reg grid
    4. strategy
      1. user enters uas code iinto 2017_000
      2. show mbox
      3. initiate call to updates


Sunday, June 19, 2016

ASA task - transform tpp xml






/Users/smr/current_projects/tpp-xml-transform/


new for 2016-06: S3-based preview workflow

/Users/smr/current_projects/tpp-xml-transform/
/Users/smr/current_projects/tpp-xml-transform/xml-to-html-preview/00-transform-and-upload.command

  1. uses the xml source found in: /Users/smr/current_projects/tpp-xml-transform/xml-source/
  2. inline css
  3. uploads html to http://media.prepware.com.s3.amazonaws.com/tpp-xml-preview




Thursday, June 16, 2016

ASA task - create new falcon db


see Prepware Updaters 02-2016 checklists google doc

checklist - create new falcon db (if necessary)

/Users/smr/current_projects/prepware-tools/create-falcon-db/

modify testmaps xls as needed
generate tab-delim txt
e.g. testmaps_2015_rev_b.txt
run 00-create-falcon.command
creates falcon db
adds topics table, referencing tab_delim/*



Wednesday, June 15, 2016

ASA task - add new skus to the act codes app



##################################################
# add new skus to the act codes app
##################################################


# add skus in code
##################################################
registrar

/Users/smr/current_projects/asa-act-codes/actcodes/app/controllers/activation_codes_controller.rb
  def validate_act_code


# add new products to db
##################################################

copy old block as sql
tweak with sublime


old:
INSERT INTO `products` (`id`, `name`, `sku`, `created_at`, `updated_at`)
VALUES
  (33, 'Airframe', 'ASA-TW-AMA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (34, 'General', 'ASA-TW-AMG-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (35, 'Powerplant', 'ASA-TW-AMP-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (36, 'Aircraft Maintenance Technician', 'ASA-TW-AMT-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (37, 'Commercial Pilot', 'ASA-TW-C-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (38, 'Certified Flight Instructor', 'ASA-TW-CFI-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (39, 'Inspection Authorization', 'ASA-TW-IA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (40, 'Instrument Rating', 'ASA-TW-I-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (41, 'Military Competency', 'ASA-TW-MIL-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (42, 'Private Pilot', 'ASA-TW-PVT-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (43, 'Bundle P-I', 'ASA-TW-PI-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (44, 'Bundle P-I-C-CFI', 'ASA-TW-PIC-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (45, 'Bundle P-I-C-ATP', 'ASA-TW-PICA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (46, 'ATP and Flight Engineer', 'ASA-TW-ATP-FE-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15');

new:
INSERT INTO `products` (`id`, `name`, `sku`, `created_at`, `updated_at`)
VALUES
  (0, 'Airframe', 'ASA-TW-AMA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'General', 'ASA-TW-AMG-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Powerplant', 'ASA-TW-AMP-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Aircraft Maintenance Technician', 'ASA-TW-AMT-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Commercial Pilot', 'ASA-TW-C-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Certified Flight Instructor', 'ASA-TW-CFI-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Inspection Authorization', 'ASA-TW-IA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Instrument Rating', 'ASA-TW-I-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Military Competency', 'ASA-TW-MIL-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Private Pilot', 'ASA-TW-PVT-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I', 'ASA-TW-PI-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I-C-CFI', 'ASA-TW-PIC-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I-C-ATP', 'ASA-TW-PICA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'ATP and Flight Engineer', 'ASA-TW-ATP-FE-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59');

Tuesday, June 14, 2016

adjust grs student record screen for small viewport sizes


evaluate getViewport fn: https://gist.github.com/oorabona/f1a062ce11936c32b51f


/Users/smr/current_projects/pws2016/app/assets/javascripts/viewport.coffee

getViewport = ->
    e = window
    a = "inner"
    unless "innerWidth" of window
      a = "client"
      e = document.documentElement or document.body
    width: e[a + "Width"]
    height: e[a + "Height"]

# https://gist.github.com/oorabona/f1a062ce11936c32b51f
# If you'd like to create top-level variables for other scripts to use, attach
# them as properties on window, or on the exports object in CommonJS.
# window.foo = "Lorem ipsum"
window.getViewport = getViewport


usage:
jQuery ->
  if $('div.ground-school').length
    # tweak layout for small devices
    if window.getViewport().width <= 480
      console.log("narrow")
      $("div.container").removeClass('container')
      $("div.content-wrapper-bordered").removeClass('content-wrapper-bordered')




notes
  1. ASA
    1. grs student record doesn't work for small phones, e.g. iphone5
      1. strategy
        1. for xs, do not render lesson-thumbnails
        2. on page load
          1. detect viewport?
          2. hide/show
          3. remove container classes on page load?


Wednesday, October 21, 2015

prepware updates 10-2015 - tweaks to fix discontiguous topic numbers


SELECT * FROM questions WHERE db_identifier='pvt' AND asachapter='11' AND topicnumber='4'

UPDATE `questions` set `topicnumber`=3 WHERE db_identifier='pvt' AND asachapter='11' AND topicnumber='4'
UPDATE `questions` set `topicnumber`=4 WHERE db_identifier='pvt' AND asachapter='11' AND topicnumber='5'
UPDATE `questions` set `topicnumber`=5 WHERE db_identifier='pvt' AND asachapter='11' AND topicnumber='6'

private chapter 11

11 1 Phraseology, Techniques, and Procedures
11 2 Airport Traffic Area Communications and Light Signals
11 3 Radar Assistance to VFR Aircraft
11 4 Transponder
11 5 Emergency Locator Transmitter (ELT)

atp chapter 5

changed my tab-delimited text (i use this to import topics into falcon) to:
5          1          Center of Gravity Computation
5          2          Stabilizer Trim Setting
5          3          Changing Loading Conditions
5          4          C208 Weight and Balance
5          5          Beech 1900 Weight and Balance
5          6          Helicopter Weight and Balance
5          7          Helicopter Weight and Balance: CG Shifts
5          8          Helicopter Weight and Balance: Load Limits
5          9          Helicopter Weight and Balance: Lateral CG
5          10        Floor Loading Limits



Thursday, August 6, 2015

notes for adding or manually tweaking PWO school/users/subscriptions


need:

  • school with act code
  • user
  • subscription with user and same act code
  • school affiliation with user and school

Saturday, August 1, 2015

troubleshoot PWO-107 wrong numq in Ground Instructor quiz


bug in a nutshell

  • generating a onestep quiz calls qdbm.qids_for_quiz_defn
  • chapter.questions with category joins is returning duplicates. e.g. book id 7, chapter 2 returns [3388, 3601, 4200, 3348, 3288, 3483, 3376, 3284, 4096, 3427, 3656, 3301, 3543, 3316, 3601]
  • need to rework to add uniq

new approach

  • add uniq get ids with out dups
  • shuffle
  • pull num ids required from shuffles list
1.9.3p286 :047 > qids=qdbm.qids_for_quiz_defn(qd); p qids.count; p qids; p qids.uniq.count; p qids.uniq!
   (0.5ms)  SELECT `categories`.id FROM `categories` INNER JOIN `categories_quiz_definitions` ON `categories`.`id` = `categories_quiz_definitions`.`category_id` WHERE `categories_quiz_definitions`.`quiz_definition_id` = 15
  Chapter Load (0.3ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 1 LIMIT 1
   (0.2ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 76 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 0
[]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
   (3.6ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 15
[3388, 3601, 4200, 3348, 3288, 3483, 3376, 3284, 4096, 3427, 3656, 3301, 3543, 3316, 3601]
  Chapter Load (0.4ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 3 LIMIT 1
   (2.8ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 78 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 9
[3368, 4084, 3448, 4110, 3441, 4055, 3438, 4111, 4105]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 4 LIMIT 1
   (2.1ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 79 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 9
[3577, 3557, 3620, 3565, 3591, 3546, 10896, 3576, 3607]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 5 LIMIT 1
   (2.3ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 80 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 15
[2940, 3064, 2978, 3000, 3042, 2926, 2961, 10847, 3048, 10948, 3026, 2942, 10949, 3011, 4129]
  Chapter Load (0.3ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 6 LIMIT 1
   (1.7ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 81 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 10
[3673, 3753, 3659, 3706, 3659, 3719, 3663, 3673, 3738, 3660]
  Chapter Load (0.3ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 7 LIMIT 1
   (1.8ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 82 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 8
[3724, 3936, 3904, 3904, 3940, 4043, 3933, 3208]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 8 LIMIT 1
   (3.2ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 83 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 15
[3081, 4224, 3272, 3222, 3127, 3197, 3195, 3186, 3266, 3172, 3228, 3080, 3246, 3162, 3198]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 9 LIMIT 1
   (3.9ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 84 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 15
[3809, 3801, 3784, 3843, 3855, 3812, 3814, 3790, 3783, 3990, 3994, 3772, 3804, 3900, 3817]
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 10 LIMIT 1
   (1.0ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 85 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 4
[3943, 4035, 3974, 4029]

100 qids pulled from QuestionDatabaseMiner
[3388, 3601, 4200, 3348, 3288, 3483, 3376, 3284, 4096, 3427, 3656, 3301, 3543, 3316, 3601, 3368, 4084, 3448, 4110, 3441, 4055, 3438, 4111, 4105, 3577, 3557, 3620, 3565, 3591, 3546, 10896, 3576, 3607, 2940, 3064, 2978, 3000, 3042, 2926, 2961, 10847, 3048, 10948, 3026, 2942, 10949, 3011, 4129, 3673, 3753, 3659, 3706, 3659, 3719, 3663, 3673, 3738, 3660, 3724, 3936, 3904, 3904, 3940, 4043, 3933, 3208, 3081, 4224, 3272, 3222, 3127, 3197, 3195, 3186, 3266, 3172, 3228, 3080, 3246, 3162, 3198, 3809, 3801, 3784, 3843, 3855, 3812, 3814, 3790, 3783, 3990, 3994, 3772, 3804, 3900, 3817, 3943, 4035, 3974, 4029]

use uniq! to get rid of duplicates, only 96 remain
[3388, 3601, 4200, 3348, 3288, 3483, 3376, 3284, 4096, 3427, 3656, 3301, 3543, 3316, 3368, 4084, 3448, 4110, 3441, 4055, 3438, 4111, 4105, 3577, 3557, 3620, 3565, 3591, 3546, 10896, 3576, 3607, 2940, 3064, 2978, 3000, 3042, 2926, 2961, 10847, 3048, 10948, 3026, 2942, 10949, 3011, 4129, 3673, 3753, 3659, 3706, 3719, 3663, 3738, 3660, 3724, 3936, 3904, 3940, 4043, 3933, 3208, 3081, 4224, 3272, 3222, 3127, 3197, 3195, 3186, 3266, 3172, 3228, 3080, 3246, 3162, 3198, 3809, 3801, 3784, 3843, 3855, 3812, 3814, 3790, 3783, 3990, 3994, 3772, 3804, 3900, 3817, 3943, 4035, 3974, 4029]

the initial array, sorted to help ferret out the duplicates
[2926, 2940, 2942, 2961, 2978, 3000, 3011, 3026, 3042, 3048, 3064, 3080, 3081, 3127, 3162, 3172, 3186, 3195, 3197, 3198, 3208, 3222, 3228, 3246, 3266, 3272, 3284, 3288, 3301, 3316, 3348, 3368, 3376, 3388, 3427, 3438, 3441, 3448, 3483, 3543, 3546, 3557, 3565, 3576, 3577, 3591, 3601, 3601, 3607, 3620, 3656, 3659, 3659, 3660, 3663, 3673, 3673, 3706, 3719, 3724, 3738, 3753, 3772, 3783, 3784, 3790, 3801, 3804, 3809, 3812, 3814, 3817, 3843, 3855, 3900, 3904, 3904, 3933, 3936, 3940, 3943, 3974, 3990, 3994, 4029, 4035, 4043, 4055, 4084, 4096, 4105, 4110, 4111, 4129, 4200, 4224, 10847, 10896, 10948, 10949]




##################################################
# chapter questions 
##################################################
1.9.3p286 :067 > chapter=Book.find(7).chapters.find_by_chapnum(2)

1.9.3p286 :067 > chapter.questions.pluck("questions.id")
   (0.9ms)  SELECT questions.id FROM `questions` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77
 => [3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3370, 3371, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3409, 3411, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3480, 3481, 3482, 3483, 3484, 3485, 3491, 3492, 3494, 3509, 3525, 3526, 3527, 3528, 3529, 3543, 3601, 3609, 3623, 3633, 3636, 3637, 3638, 3639, 3640, 3642, 3652, 3653, 3654, 3655, 3656, 3657, 3890, 3891, 3893, 3894, 3895, 3896, 3897, 3898, 3992, 4002, 4003, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4057, 4058, 4059, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4094, 4096, 4097, 4098, 4200, 4201] 
217 records
1.9.3p286 :092 > Book.find(7).chapters.find_by_chapnum(2).questions.pluck("questions.id").count
 => 217 

no duplicates
1.9.3p286 :079 > Book.find(7).chapters.find_by_chapnum(2).questions.pluck("questions.id").uniq!
 => nil 


chap 2
   Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
  (3.7ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19)) ORDER BY RAND() LIMIT 15


##################################################
# adding the category where clause 
##################################################
1.9.3p286 :101 > Book.find(7).chapters.find_by_chapnum(2).questions.joins(:categories).where("category_id in (3,4,10,11,12,15,17,19)").where(deprecated:false).pluck("questions.id")
  Book Load (0.3ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 7 LIMIT 1
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
   (3.8ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19))
 => [3274, 3278, 3279, 3280, 3281, 3282, 3284, 3291, 3292, 3301, 3302, 3304, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3330, 3331, 3334, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3480, 3481, 3482, 3483, 3484, 3485, 3543, 3601, 4096, 4097, 4098, 4200, 3275, 3277, 3283, 3285, 3286, 3287, 3288, 3289, 3290, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3303, 3305, 3306, 3329, 3332, 3333, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3609, 3278, 3281, 3282, 3284, 3299, 3304, 3306, 3308, 3309, 3310, 3311, 3331, 3334, 3348, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3414, 3415, 3416, 3417, 3480, 3481, 3482, 3483, 3484, 3485, 3509, 3601, 3638, 3639, 3640, 3642, 3992, 4096, 4097, 3274, 3278, 3279, 3280, 3281, 3282, 3284, 3291, 3292, 3301, 3302, 3304, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3330, 3331, 3334, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3480, 3481, 3482, 3483, 3484, 3485, 3543, 3601, 4096, 4097, 4098, 4200, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3525, 3526, 3527, 3528, 3529, 3652, 3653, 3654, 3655, 3656, 3657, 4002, 4003, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 3278, 3280, 3284, 3292, 3301, 3302, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3323, 3324, 3325, 3326, 3327, 3331, 3345, 3346, 3347, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3543, 3601, 4057, 4058, 4059, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4085, 4094, 4096, 4097, 3276, 3370, 3371, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3409, 3411, 3413, 3491, 3492, 3494, 3623, 3633, 3636, 3637, 3890, 3891, 3893, 3894, 3895, 3896, 3897, 3898, 4201, 3278, 3279, 3280, 3284, 3292, 3301, 3302, 3304, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3330, 3331, 3334, 3345, 3346, 3347, 3348, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3543, 3601, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4096, 4097, 4200] 
1.9.3p286 :102 > Book.find(7).chapters.find_by_chapnum(2).questions.joins(:categories).where("category_id in (3,4,10,11,12,15,17,19)").where(deprecated:false).pluck("questions.id").count
  Book Load (0.3ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 7 LIMIT 1
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
   (3.7ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19))
 => 393 


##################################################
# duplicates related to the join
##################################################
http://stackoverflow.com/questions/38549/difference-between-inner-and-outer-joins
e.g.
3279  cfi 6506  PLT477  2 5 AIR, LSA, WSC   An airplane would have a tendency
3279  cfi 6506  PLT477  2 5 AIR, LSA, WSC   An airplane would have a tendency
3279  cfi 6506  PLT477  2 5 AIR, LSA, WSC   An airplane would have a tendency
3280  cfi 6507  PLT242  2 4 AIR, LSA, WSC, PPC    When considering the forces
3280  cfi 6507  PLT242  2 4 AIR, LSA, WSC, PPC    When considering the forces
3280  cfi 6507  PLT242  2 4 AIR, LSA, WSC, PPC    When considering the forces
3280  cfi 6507  PLT242  2 4 AIR, LSA, WSC, PPC    When considering the forces

##################################################
# resolve with uniq 
##################################################
1.9.3p286 :105 > Book.find(7).chapters.find_by_chapnum(2).questions.joins(:categories).where("category_id in (3,4,10,11,12,15,17,19)").where(deprecated:false).pluck("questions.id").uniq
  Book Load (0.3ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 7 LIMIT 1
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
   (3.8ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19))
 => [3274, 3278, 3279, 3280, 3281, 3282, 3284, 3291, 3292, 3301, 3302, 3304, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3330, 3331, 3334, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3480, 3481, 3482, 3483, 3484, 3485, 3543, 3601, 4096, 4097, 4098, 4200, 3275, 3277, 3283, 3285, 3286, 3287, 3288, 3289, 3290, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3303, 3305, 3306, 3329, 3332, 3333, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3609, 3414, 3415, 3416, 3417, 3509, 3638, 3639, 3640, 3642, 3992, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3525, 3526, 3527, 3528, 3529, 3652, 3653, 3654, 3655, 3656, 3657, 4002, 4003, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4057, 4058, 4059, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4085, 4094, 3276, 3370, 3371, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3409, 3411, 3413, 3491, 3492, 3494, 3623, 3633, 3636, 3637, 3890, 3891, 3893, 3894, 3895, 3896, 3897, 3898, 4201, 4086, 4087, 4088, 4089, 4090, 4091, 4092] 
1.9.3p286 :106 > Book.find(7).chapters.find_by_chapnum(2).questions.joins(:categories).where("category_id in (3,4,10,11,12,15,17,19)").where(deprecated:false).pluck("questions.id").uniq.count
  Book Load (0.4ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 7 LIMIT 1
  Chapter Load (0.2ms)  SELECT `chapters`.* FROM `chapters` WHERE `chapters`.`book_id` = 7 AND `chapters`.`chapnum` = 2 LIMIT 1
   (3.7ms)  SELECT questions.id FROM `questions` INNER JOIN `categories_questions` ON `categories_questions`.`question_id` = `questions`.`id` INNER JOIN `categories` ON `categories`.`id` = `categories_questions`.`category_id` INNER JOIN `book_mappings` ON `questions`.`id` = `book_mappings`.`question_id` WHERE `book_mappings`.`chapter_id` = 77 AND `questions`.`deprecated` = 0 AND (category_id in (3,4,10,11,12,15,17,19))
 => 217