Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Break HTML table output into two or three columns

by Jagtig (Initiate)
on Feb 13, 2017 at 18:06 UTC ( [id://1181910]=perlquestion: print w/replies, xml ) Need Help??

Jagtig has asked for the wisdom of the Perl Monks concerning the following question:

I need to add a code snippet to a quiztest (tesol) script that will break the output of the multiple choice table into two, or preferably three columns. At present, the script prints only one column of options for answers in a multiple choice quiz.

I have looked at it closely, and the html is actually very simple. However, the Perl is absolutely beyond me. As you know, Perl is very speedy, but breaks very easily, so I am not even going to try. When it breaks on my server, Site5, it really breaks, and has to be deleted and set up, again.

http://mywebsiteweb.com/cgi-bin/quiztest.cgi?antiquitycc1 Here's another showing the 17 option quiztest: http://mywebsiteweb.com/AllArtHistoryQuizzes/ProfessorBarnes/quiztest.cgi?workingtemplate

As you can see after you've opened this quiz with the password "pass," I can make any number of answer options. I have completed a 17 answer template, but could go up to thirty, considering my subject matter is all the artists in a given movement, or school.

To do so, it would be best to break the output of the input to three, or so, columns. The script is a free download from Tesol, and that's what I suggest using, since mine has been edited, and you don't want to work on something edited by me, I'm pretty sure. http://tesol.net/scripts/quiztest.zip

Here is the place in the code that the table-making command has to be edited.

Below is the code closest to the critical area. If you find it using your find option on your keyboard (ctrl-f), you will be pretty close to the point where it has to be changed to make the questions and multiple choice answer in three or more columns.

<b>Quiz and Quiz Takers</b></td></tr> <tr><td align=left colspan=2> On the left, enter the questions and the possible answers. Hint: To enter a Short-Answer question, type the question as usu +al, make sure to check the box for whether you want the student to have a single-line text field or a multi-line text field for filling in their answers. <br><br>To give multiple options for a Short-Answer field, separate the options with two forward slashes (//), e.g.: \"Yes//Yep//Yeah//Yessir\". Be sure to mark it as correct. If you are using the \"authorized users\" function, select the checkboxes next to the students who are allowed to take this qui +z. <hr> </td></tr> <tr><th>Quiz Info</th><th>Authorized Students $select_all_students_html </th></tr> <tr><td valign=top> <table border=0> <tr><th rowspan=2>Question</th><th rowspan=2>Possible Answers</ +th> <th colspan=2>Short-answer questions</th></tr> <tr><th><font size=2>Single-line text field</font></th> <th><font size=2>Multi-line text field</font></th></tr>";

If you don't have a quickie answer, I can do the whole thing in a numbered line examination, but like I said, I know nothing of Perl, and have spent most of my time and energy on Php.

Thank you, again! Jagtig

Also, I can make a donation, but not a great one.

<code> The remainder of the quiztest.cgi (perl) script apart from it's download folder

#!/usr/bin/perl # NOTE: the above line must be changed to show the path to the # Perl interpreter on your system! Leave the #! as is, but # the path may have to be changed if yours is different. # DO NOT CHANGE the LINE BELOW. use CGI::Carp qw(fatalsToBrowser); $| = 1; &clear_all(); ###################################################################### +### # QuizTest 3.0.31 # # CGI quiz program for the worldwide web. May use multiple choice or + # # true/false questions. The program grades the quiz, shows students + # # their score, then emails the results to the designated instructor. + # # Intended for online courses that are graded. # # Copyright 1996 - 2002, Kristina L. Pfaff-Harris # # All rights reserved. + # # # ###################################################################### +### ##### Licensing: + # ##### + # ##### This program may be used free of charge under the following + # ##### conditions: + # ##### + # ##### 1. All instructions and Copyright lines must remain unchanged. + # ##### + # ##### 2. All pages generated by the program must contain one of the + # ##### following pieces of HTML code: + # ##### + # ##### <font size=-2>This quiz engine uses QuizTest by + # ##### Kristina Pfaff-Harris. It can be found at: + # ##### <a href="http://www.tesol.net/scripts/"> + # ##### http://www.tesol.net/scripts</a></font> + # ##### OR: + # ##### <!-- QuizTest is Copyright 1996-2002 Kristina Pfaff-Harris - +-># ##### <!-- Get it at http://www.tesol.net/scripts/ --> + # ##### + # ##### 3. You may not sell or distribute this program. You may charge + # ##### a reasonable fee for installing it for a client as long as + # ##### you make it clear that you are not the author, and you are + # ##### not selling the program to them: only charging for installin +g # ##### it. + # ##### + # ##### 4. You agree that this program is offered without warranty of + # ##### any kind, including warranty of fitness for a particular + # ##### purpose. You further agree that the author and all sites + # ##### associated in any way with this program are not liable for + # ##### any damage or loss incurred as a result of using this progra +m.# ###################################################################### +### ##### + # ##### IMPORTANT INSTRUCTIONS: + # ##### + # ##### In this program, I have put **CHANGE** in all the places where + # ##### you will need to modify the program to run on your server, so + # ##### that you can easily find all the places where changes are + # ##### necessary. This program must be chmod 755 or 775 in order to + # ##### work, and the directory where you want QuizTest to put its files + # ##### must be chmod 777. # ##### + # ##### In addition, if you wish to use the option that will email you + # ##### the results every time a student takes one of the quizzes, + # ##### and your website is hosted on a Unix or Linux-based web server, + # ##### you must have the sendmail program on your web server, and your + # ##### web server must have permission to access it as well as + # ##### permission to run cgi programs. + # ##### + # ###################################################################### +### # # # IMPORTANT: If you FTPed this program to your server in "binary" mode +, # # it will NOT work! If you're not sure, please go back and FTP it +# # to your server again and make sure you use "ascii" mode. If you get + # # "500 Server Error", this is almost always the cause. :) # # # # Using the program: # # This program requires the file "quiztest.cgi" at a minimum in order + # # to work. Please read the README.quiztest file for more information. + # # Please read the manual (Manual.html) and check the Scripts for # # Educators FAQ first (http://tesol.net/scripts/FAQ/) if you have # # problems. If none of that helps, email me and I'll at least try to + # # help. :-) # # # # I hope this program proves useful to you! Please contact me # # (http://tesol.net/scriptmail.html) for any bugs or feedback. +# ###################################################################### +### # Special thanks to Selena Sol (http://www.extropia.com) for + # # MultipleChoice 2.0 which helped me get started on my very first quiz + # # program in Perl. # ###################################################################### +### %data = &get_data(); if($data{'FA'} ne "ExportToAscii"){ print "Content-type: text/html\n\n"; } ###################################################################### +### ##### # ##### BEGIN SECTION WHERE YOU WILL NEED TO CHANGE THINGS: # ##### # ##### In this section, there are several places where you'll need + # ##### to make changes. Please read all instructions carefully # ##### before you make the changes. # ##### # ###################################################################### +### # $basedir: This is the base directory on your server where your # course materials are located. This is used by the # program to store the results file separately for each # lesson. *CHANGE* this to the full base system path # to where you want QuizTest to put all its quiz files # and so forth. Please see the README.quiztest file under # "Setting up Files, Directories, and Permissions" for more # information about $basedir, and how to set it up. # Please note that this is NOT a URL, and should NOT # contain "http://" # # If your web server is a Unix-type system, then this # MUST begin a /, and the folder must be writeable # by the web server. For example: # $basedir = "/path/to/your/files"; # # If your web server is a Windows-type system, then this # MUST begin a "c:" or "d:" or "e:". For example: # $basedir = "c:/path/to/your/files"; $basedir = "/path/to/your/files"; # $cgi_url is the full web address of your quiztest.cgi program. # This MUST start with "http://" or it will not work. Please # **CHANGE** this to the actual web address of where you have # installed the quiztest.cgi program. $cgi_url = "http://www.your_domain.com/cgi-bin/quiztest.cgi"; ################################################################### # # # Operating System Specific Stuff # # (Windows vs. Unix/Linux) # # # ################################################################### # In this section, we're going to try to get some data that will # help us run this script whether you're using Windows NT/95/98 as # a web server, or a Unix/Linux-based web server. Here, I feel # it necessary to point out that Unix/Linux web servers tend to # be much more flexible and robust (in my experience) than Windows # ones. However, if you're stuck with Windows, we'll try to get # this working anyway. :) # If your web server is Linux/Unix based, please set # $opsys below to "unix" like this and go to the Unix/Linux Stuff # Section below: # $opsys = "unix"; # Otherwise, if it is a Windows-based platform, set $opsys to "win" # like this and go to the Windows Stuff section: # $opsys = "win"; $opsys = "unix"; ################################################################### # # # Unix/Linux Stuff # # # ################################################################### # $path_to_sendmail needs to be the FULL path to sendmail on your # server, and the name of the sendmail file itself: You will # probably be able to use what I have below, but sendmail # is sometimes located in /usr/ucblib instead of /usr/lib and # may be somewhere else altogether. Ask your systems administrator # where sendmail is, just to make sure, then **CHANGE** this to # the correct path. Note: on some systems, this is something # totally different without the word "sendmail" at all such as # "/var/qmail/bin/qmail-inject". $path_to_sendmail = "/usr/sbin/sendmail"; ################################################################### # # # Windows Stuff # # # ################################################################### # $mail_server_hostname needs to be the hostname of a mail server # that your web server is allowed to send mail through. Generally, # this will be something like "mail.yourdomain.com" but it may # be something completely different, and you may not be able to # use this at all. If your web server is also a mail server, # you may be able to use "localhost" (yes, just that one word, # no ".com" or anything -- it's a special word that means "this # machine.") You will need to ask your local technical support # people for your website what hostname to use for your outgoing # mail server, then **CHANGE** this to reflect that. For example: # $mail_server_hostname = "mail.yourdomain.com"; $mail_server_hostname = "mail.yourdomain.com"; # $this_server_hostname needs to be the hostname of your web # server where this script will be run. Sometimes, just the # "www.yourdomain.com" will work, and sometimes your web # server has its own name like "web-01.nt.somedomain.com". # Again, you will need to get the hostname of this machine # from the technical support people for your web server, # and **CHANGE** this to reflect what they say. For example: # $this_server_hostname = "www.yourdomain.com"; $this_server_hostname = "localhost"; # IMPORTANT: DO NOT CHANGE $smtp_auth UNLESS YOU KNOW THAT YOU NEED # TO USE IT. Please look for "SMTP auth" in the FAQ if you have # questions (http://tesol.net/scripts/FAQ/) # Okay, you may NOT need these. If you're sending mail okay, then don' +t # change the next two things. However, if you're having problems with # your mail server requiring authentication to send mail, you may try # one of these EXPERIMENTAL authentication thingies. # $smtp_auth is what kind of authentication you want to try to push # the mail past the mail server. # $smtp_auth = "POP"; is for "POP before SMTP" # $smtp_auth = "SMTP"; is for "PLAIN SMTP auth" # $smtp_auth = "NONE"; is normal. $smtp_auth = "NONE"; # If you are using POP or SMTP auth above, you must put the username # and password of an email account located on the mail server you # put in $mail_server_hostname here. # NOTE: If there are any ", $, or @ signs in your username or password +, # you must put a \ (backslash) in front of them. For example, if your # password is 1$jk"yn@, you would put: # $pop_pw = "1\$jk\"yn\@"; # **CHANGE** "your email login" below to your email username on the # mail server you'll be using. # **CHANGE** "your email password" below to your email password on the # mail server you'll be using. $pop_un = "your email login"; $pop_pw = "your email password"; # If you are using POP or SMTP auth above, you may need to also # specify your email address on that mail server. I know, for example, # that if you have email at softhome.net, you will HAVE to use your # softhome.net email address even if you have used the authentication # above. **CHANGE** this to your actual email address if you have # chosen POP or SMTP auth above. $auth_from_address = "webmaster\@your_domain.com"; ################################################################### # # # End of Operating System-Specific stuff. On to more changes: # # # ################################################################### # $webmaster: This is just a generic name for the "From" field # You'll want to *CHANGE* "WebMaster" to something # appropriate for your site. It can be anything from your # real name to "Master of the Universe," whatever # suits your fancy. $webmaster = "QuizTest v3.0.31"; # $webemail: This is also a generic address for the "From" field # *CHANGE* "webmaster\@mysite.edu to the webmaster address + # for your website, or to your own address. $webemail = "webmaster\@mysite.edu"; # $instructor: # This is the email address of the person who should get # the results of any quizzes not otherwise assigned to # an instructor. You will need to set $instructor to the # email address of the person who should get the results # of the quizzes after they are taken. **CHANGE** this # to your own or other appropriate email address. NOTE: # You must put a \ (backslash) in front of the @ sign # like this: \@ # IMPORTANT: This is also what you will use as the username # to log into the administrative section of the program. $instructor = "you\@yoursite.edu"; # Now, you'll need to select a password of sorts. Please note # that this does NOT make the admin functions secure, it just # makes it a little more secure than if the password were # "admin" as it is by default, or if there were no password. # You will use this to log into the admin screen. # So, **CHANGE** $admin_password = "admin"; to # $admin_password = "something_else"; here. The only restriction # is it cannot contain the "|" (pipe) symbol. $admin_password = "admin"; # $multiple_instructors : # This allows you to determine whether or not you wish to have # multiple instructors, one for each quiz. If you **CHANGE** # $multiple_instructors = "no"; to # $multiple_instructors = "yes"; # then the program will create a file for the instructors in # whatever folder you set up as $basedir. This will keep track # of instructors and which quizzes they are responsible for. $multiple_instructors = "yes"; # $show_scores_for_all_quizzes : # If this is set to Yes, then users can click a link and see just # the high scores for a quiz without actually taking a quiz. If this # is set to No, then the link will not appear. $show_scores_for_all_quizzes = "Yes"; ###################################################################### +### # # # IMPORTANT: The rest of these options may be changed for each +# # individual quiz through the web-based quiz creation interface. +# # It is not necessary to change these settings here, as you may # # override them when creating or editing a quiz. However, you may + # # wish to read through them and make sure the default settings are + # # satisfactory to you, and **CHANGE** them if you need to do so. +# # # ###################################################################### +### # $debugging: Okay, first of all, if you're having problems with the # script, and $debugging is not set to 1, then you will want to **CHAN +GE** # $debugging = 0; to $debugging = 1; # What this will do is print out some helpful information about why # the script might not be working for you. If it's not helpful to # you, then it will definitely be helpful to me when you email me # for help! If you want, you can set this right off the bat to be # sure that all the files and so forth are in the right place. Just # be sure to turn it back to 0 before you actually use the program, # or your users will get all these funny messages about files and # directories. # This setting may be changed for each quiz when you create or # edit a quiz. # This is set to 1 by default to help you install QuizTest. **CHANGE** + it # to 0 when you feel that it's all working properly. $debugging = 1; # Now, it is sometimes helpful to be able to turn on debugging # without coming in here and editing this file. $remote_debugging # lets you determine whether or not you want to be able to # turn on debugging by calling the quiztest.cgi program like # this: # # http://www.your.site/cgi-bin/quiztest.cgi?debugging=1 # # If you set $remote_debugging = "on"; then you will be # able to turn debugging on by calling the script like I # have it above. Note: this means that anyone else can # turn debugging on as well. It shouldn't really hurt anything, # but some people are sensitive about outside people knowing # where their files are and so forth. If you set # $remote_debugging = "off"; then you will have to edit # the script, and set $debugging = 1; if you want debugging # information at all. **CHANGE** this to the appropriate # setting. # This setting may be changed for each quiz when you create or # edit a quiz. $remote_debugging = "off"; # This next is for purely aesthetic purposes. Basically, you can have # any HTML code you like appear at the top of the pages generated by # the program, and at the bottom. If you don't know much about HTML # code, then I suggest you leave this alone. If you change it, then # all of the following characters # " @ \ % $ # MUST have a backslash in front of them. For example: # \" \@ \\ \% \$ # If you aren't extremely careful with this, the program will not run. # You may **CHANGE** $header = "<html>...etc to contain the appropriat +e # HTML code for your site. $header = " <HTML><head><title>QuizTest v3.0.31</title></head> <body bgcolor=\"#FFFFF0\"> <center><font size=+2>QuizTest!<br><BR> <br><br> </font></center> <br> <P> "; # $footer is pretty much the same deal as $header above: this HTML # is at the end of all pages generated by the program. $footer =" </body></html> "; # $grade_quiz_button_text is so that if you would like to change # what the "Grade Quiz" button on the quizzes says, you can do that. # This will not affect the operation of the program, so you can leave # it the way it is if you like. Please make sure to put a \ (backslas +h) # in front of any of the following characters: # @ $ " % \ # like this: # \@ \$ \" \% \\ $grade_quiz_button_text = "Grade Quiz"; # $mail_me_results lets you tell the program whether you want the # results of the quizzes emailed to you or not. I put this in so # that I could turn off emailing on the demo script: otherwise, # I'd get inundated with emailed quizzes from people trying out the # program. You should **CHANGE** this to # # $mail_me_results = "Yes"; # # or you will never get the results of the quizzes! NOTE: If you set # this to Yes, it will only email you the first time someone takes the # quiz. If you set $mail_me_results = "All"; then it will email you al +l # the results any time someone takes the quiz. $mail_me_results = "No"; # $take_quiz_over : # If you **CHANGE** $take_quiz_over = "no"; to # $take_quiz_over = "yes"; # then students will be allowed to take any quiz more than once. $take_quiz_over = "yes"; # $scores_to_save : # If you have set $take_quiz_over to "yes", you will need to decide # which scores you want to save. By default, QuizTest will only save # the FIRST result: Any other attempts at the quiz will not be saved, # since we tend to assume that anyone can pass the quiz just by trial # and error, given enough attempts. However, some people wish to save # all the results, and some wish to save only the last result. # Here are the possible settings you can use: # To save ONLY the first attempt: # $scores_to_save = "first"; # To save ONLY the last attempt: # $scores_to_save = "last"; # To save the scores from ALL attempts: # $scores_to_save = "all"; $scores_to_save = "first"; # $force_complete_quiz is whether or not you want to have the # script check to make sure that all questions have been answered # on a quiz. If you set # $force_complete_quiz = "yes"; # Then quiz takers will have to answer all questions on a quiz bef +ore # it can be graded. If you set # $force_complete_quiz = "no"; # Then quiz takers will be able to submit only partially-completed # quizzes. $force_complete_quiz = "yes"; # $authorized_users : # This lets you decide whether just anyone can take the quiz, # or only registered students. If you **CHANGE** # $authorized_users = "no"; to # $authorized_users = "yes"; # then you must add each student to the system through the # admin interface. $authorized_users = "no"; # $what_to_show_after_quiz is designed to let you determine whether # or not to show the users whether their individual answers were # correct or incorrect, and whether to show their score or not. # The idea behind this is that if you show the score, the user could # keep hitting the "Back" button on the browser, and changing answers # until they got a perfect score, after which they could share the # correct answers to those questions with all their friends. This # setting has 4 options: # # To show the Correct answer if the user got the Incorrect answer, and # show the total score (e.g. 50%, 100%) set this to: # # $what_to_show_after_quiz = "All"; # # To tell users whether each answer was Correct or Incorrect, but not # tell them what the correct answer actually was if they got it wrong, # and to show the total score, set this to: # # $what_to_show_after_quiz = "StatusOnly"; # # To show only the total percentage score with no feedback about which # answers were correct or incorrect, set this to: # # $what_to_show_after_quiz = "ScoreOnly"; # # To show no results at all, but rather the message "Thank you for # taking this test, <their name>. You will be notified # of your score when this test is closed," set this to: # # $what_to_show_after_quiz = "None"; $what_to_show_after_quiz = "ScoreOnly"; # $show_quiz_questions tells whether or not you'd like to display # the quiz questions, as well as the answers and/or score in the # results as shown above. If you would like QuizTest to display # and email the questions along with the answers, **CHANGE** # $show_quiz_questions = "no"; to # $show_quiz_questions = "yes"; # If you would like QuizTest to only display/email the questions to # the instructor, but not to the student, **CHANGE** # $show_quiz_questions = "no"; to # $show_quiz_questions = "instructor"; # Please note that if you have HTML code or embedded sounds, images, # etc in your questions, this may have some very strange results. # You may also set this "per quiz". $show_quiz_questions = "yes"; # $show_other_scores should be "Yes" or "No". If you set # $show_other_scores = "Yes"; then the program will not only # show the user his score, but will show the top scorers out # of others who have taken the quiz. Most people using this # for educational purposes will leave this at "No" while # people using this for amusement may wish to put it to "Yes" # If you do **CHANGE** this to $show_other_scores = "Yes"; then # you will need to tell how many scores to show in # $number_of_scores_to_show below. $show_other_scores = "No"; # $number_of_scores_to_show should be the number of previous # quiz scores you wish to show to each person who takes a quiz. $number_of_scores_to_show = "10"; # $show_grading_scale should just be "Yes" or "No". If it is # "Yes", then you may wish to edit $grading_scale below to something # appropriate for your setting. If it is "No" then the grading # scale will not be shown at all. **CHANGE** this to # $show_grading_scale = "No"; # if you don't wish to show a grading scale like the one below. $show_grading_scale = "Yes"; # $grading_scale is just something to print out to tell students # what their percentage score equals in terms of the A-F grading # scale. You may edit this as you please, or delete it entirely # if you do not choose to show a grading scale at all. You may # **CHANGE** any of the text in between <!-- Grading scale starts here + --> # and <!-- Grading scale ends here -->, and may use any HTML code # you wish to make it pretty. However, please be aware that if you # use any of the following characters: # @ $ \ " # you must put a backslash \ in front of them like this: # \@ \$ \\ \" # or the program will not work. $grading_scale = " <!-- Grading scale starts here --> <pre> ====================== | Score | Grade | |-----------|--------| | 100 - 93% | A | | 93 - 90% | A- | | 89 - 85% | B | | 84 - 80% | B- | | 79 - 75% | C | | 74 - 70% | C- | | 69 - 65% | D | | 64 - 60% | D- | | 59 - 0% | F | ---------------------- </pre> <!-- Grading scale ends here --> "; ################################################################### # # # Options for Short-Answer scoring. PLEASE Read Carefully!!! # # (These may also be changed on a per-quiz basis.) # # # ################################################################### # # Now, QuizTest will support "short answer" questions. However, # being a computer program and not a person, it does not have good # judgement about scoring, and would be extremely strict if left to # its own devices. For example, if the correct answer were "no." and # the student were to type in the answers "No." or "no" in the form, # QuizTest would count both of those wrong. Good for a spelling test, # rather inconvenient for an essay test. Here, we try to give you some + # leeway. The following $sa_blahblah variables are designed to moderat +e # this behavior a bit. **CHANGE** each of these to "yes" or "no" as # you please, after reading the description. # # I strongly suggest that you experiment with these settings a bit # before working with short-answer questions. If nothing else, please # remember that a computer program is no substitute for a human grader +, # and any short-answer questions you have should be reviewed by a pers +on # before counting the student out for them. # # $sa_ignorecase = "yes"; # Tell QuizTest to ignore differences in case, so that "no", "No", a +nd # "NO" will all be counted as correct if the answer is "No." # If you don't want this, **CHANGE** this to "no". $sa_ignorecase = "yes"; # $sa_ignorepunctuation # Tell QuizTest to ignore punctuation, so that '"Yes," she answered. +' # will be counted the same as 'Yes she answered' or 'Yes, she answer +ed' # This is a bad idea if you plan to do Math or Science quizzes, sinc +e # 1/4 would ignore the "punctuation" sign "/" and 14 would be counte +d # as a correct answer! # If you do want this, **CHANGE** this to "yes". $sa_ignorepunctuation = "no"; # $sa_ignorespaces # Tell QuizTest to ignore differences in spaces between words, so th +at # "Yes I do" will be the same as "Yes I do" and "YesIdo". # If you don't want this, **CHANGE** this to "no". $sa_ignorespaces = "yes"; # $sa_ignorenonwords # Tell QuizTest to ignore spaces *and* punctuation, and basically ju +st # make sure that everything else is in there. # This is a bad idea if you plan to do Math or Science quizzes, sinc +e # 1/4 would ignore the "punctuation" sign "/" and 14 would be counte +d # as a correct answer! # If you do want this, **CHANGE** this to "yes". $sa_ignorenonwords = "no"; # $sa_containsanswer # This tells QuizTest that if student enters anything that is part # of the correct answer, to score it correct. This is pretty lenien +t, # as students entering "e" will be marked correct when the correct # answer is "antidisestablishmentarianism". # If you DO want this, **CHANGE** this to "yes". $sa_containsanswer = "no"; # $sa_markallcorrect # This tells QuizTest that if student enters anything *at all* # in a short answer slot, to count it as correct. This is the most # lenient of all. # If you DO want this behaviour, **CHANGE** this to "yes". $sa_markallcorrect = "no"; # $sa_alternates = "yes"; # When you create a quiz, you may give alternate answers for a short +- # answer question. For example, "behavior/behaviour" or "color/colou +r". # This tells QuizTest that it is to treat each alternate as a correc +t # answer. # If you don't want this, **CHANGE** this to "no". $sa_alternates = "yes"; ###################################################################### +### ##### # ##### END SECTION WHERE THINGS NEED TO BE CHANGED. # ##### # ##### You should not HAVE to change anything beyond this point, + # ##### although you might want to read through it to see what it doe +s. # ##### If you're interested in how CGI programs work, then this may + # ##### act as its own tutorial of sorts. You definitely shouldn't + # ##### change anything beyond this point unless you know what you're + # ##### doing, though. :) + # ##### # ###################################################################### +### # This just gives us some useful debugging information. if($data{'debugging'} && $data{'debugging'} == 1){ $data{'remote_debug'} = 1; } # Grr. Workaround for buggy IIS servers that either don't support GET # at all or that only support key=value. if($ENV{'QUERY_STRING'} eq "" && $data{'method'} ne ""){ $ENV{'QUERY_STRING'} = $data{'method'}; } if($ENV{'QUERY_STRING'}){ $ENV{'QUERY_STRING'} =~ s/&debugging=\d//g; $ENV{'QUERY_STRING'} =~ s/debugging=\d//g; } # We cannot do anything if we can't write to $basedir or if it doesn't # exist. So, let's check before we do anything else. &no_basedir_error(); # I really hate to do this, but do you have any idea how many people # never change the password from "admin" to something else? Quite a # few, unfortunately. So now, if you haven't changed it, you will be # yelled at until you do. :-) # However, the password IS "admin" on my demo, so I don't want it to # yell at me when it's on my site. :-) if($ENV{'SERVER_NAME'} !~ /linguistic-funland.com$/i && $ENV{'SERVER_NAME'} !~ /tesol.net$/i){ if($admin_password eq "admin"){ print "<br><center><table border=1><tr><td bgcolor=\"#FFFFFF\"> <font color=\"#FF0000\" size=+2><b>WARNING! You have not changed the administrative password from its default. This means that anyone can find out what it is and do things to your QuizTest system. This message will only appear until you change \$admin_password = \"admin\"; in the script to use another password.</b></font></td></tr></table></center><br>"; } } $0 = "QuizTest v3.0.31"; # We need to keep track of the real, hard-coded admin so we can let he +r # edit or delete others' students if necessary. $overall_admin = $instructor; $quizresultsemail = $instructor; &debug("<font size=+1>IMPORTANT: If you need help with setting this up +, Please copy and paste all of this debug output into an email, describe the problem you are having, and send it to me. It will make helping much easier! NOTE: A lot of the debugging information is just that: information. Errors are things like \"Cannot open file\" or \"Could not read file\" or \"Could not find something\". If the script seems to be working as you expect other than printing out these messages, then it's probably okay. :-)<br><br> When the script is set up, and functioning properly, set \$debugging = 0; in the script and you will no longer see these messages. </font><br>"); &debug("Web Server software is $ENV{'SERVER_SOFTWARE'}") if $ENV{'SERVER_SOFTWARE'}; &debug("Base path to website files is $ENV{'DOCUMENT_ROOT'}") if $ENV{'DOCUMENT_ROOT'}; &debug("Base path translated is $ENV{'PATH_TRANSLATED'}") if $ENV{'PATH_TRANSLATED'}; &debug("Script is set as $cgi_url"); &debug("Script filename is $ENV{'SCRIPT_FILENAME'}") if $ENV{'SCRIPT_FILENAME'}; &debug("Server O/S is $^O") if $^O; ################## Define the variables to be used ################### +## # $basedir should not end with a "/", so we'll take it off in case the +y # put one on. $basedir =~ s/\/$//g; # $Name: you must have an input field on your form that says name="nam +e" # This is generated by the program if you use it to make quizzes. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $Name =$data{"name"}; # $Email: one input field on your form must say name="email" # This is also generated on the form by the program. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $Email =$data{"email"}; # $soc: On mine, this was intended for the students' social security # number. Your form must have an input field with name="SSN" # on it for this to work, so the program just sets this to N/A # if you decide you don't want it or need it. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $soc =$data{"SSN"}; # $url: This makes sure that you can have several different quizzes # in different directories, and that the program will refer # the student to the correct quiz form if they need to go back # and try again. For example, if they forget to enter their # name and email address, the program will print a page that # tells them so and makes them go back again. $url =$ENV{'HTTP_REFERER'}; # $lessondir: This is the name of the directory where the quiz files # are kept. There should be a hidden field in your form # with this information. eg: # # <input type=hidden name="Lessondir" value="lesson1"> # # When the program looks for the answerfile, it will # look in the directory $basedir$lessondir/, or, in # this case /path/to/my/files/lesson1/ . # This is generated automatically by quiztest.cgi as of QuizTest v3.0 # Get it from the form's hidden field $lessondir =$data{"Lessondir"}; # Remove anything that is not a word character, and lowercase it. $data{'Lessondir'} =~ s/\W+//g; $data{'Lessondir'} =~ tr/[A-Z]/[a-z] +/; $lessondir =~ s/\W+//g; $lessondir =~ tr/[A-Z]/[a-z]/; # Now, make sure that only a-z and 0-9 (and _) are allowed in there. $lessondir =~ /^(\w+)$/; $lessondir = $1; $data{'Lessondir'} =~ /^(\w+)$/; $data{'Lessondir'} = $1; # $lesson: This is the name of the lesson. It is used by the program + # when it prints the results of the quiz. For example, if # I had one quiz for Grammar and another one for Arithmetic, # I would put a hidden field in each separate quiz with a # name="Lesson" tag. (<input type=hidden name="Lesson" value= # "Grammar">) and the student would see: "Results of the # Grammar quiz for Student's Name:" and I would also be told # that it was the Grammar quiz when the results were mailed # to me. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $lesson =$data{"Lesson"}; # $answerfile: This is very important. For each quiz, you must have a +n # HTML form AND a text file containing the answers to # the questions for the quiz. Using the "$basedir" # variable which we defined above means that you can # have a different answerfile for each quiz. (I put # my quizzes each in a separate directory so that I # don't have to have different names for each answerfile.) # The answer file must be a "pipe delimited database". # All that means is that you have to have the question # number, a "pipe" | and the answer. Like this: # # 1|true # 2|false # 3|false # # And so on. You'll need a separate one for each quiz, so # they and the quizzes should be kept together in separate # directories. These are generated by the program. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $answer_file = "$basedir/$lessondir/answerfile"; # $instructors_file : # This is the full system path to a file where you'd like to # keep track of instructors' email addresses and which quizzes # each one is responsible for. On Unix-based systems, it will # look something like this: "/home/users/public_html/instructors". # On Windows-based systems, it will probably look like this: # "C:/inetpub/wwwroot/yourname/instructors". **CHANGE** this # to the real path to that file (including the filename). This # file must be chmod 766 or otherwise set up so that the web # server can write to it. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $instructors_file = "$basedir/instructors"; # $authorized_users_file : # This is the full system path and name of the file that you # want to use to keep track of authorized students. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $authorized_users_file = "$basedir/auth_users"; # $results_database: This is the file where the results for all peopl +e # taking the quiz will be stored. You can pick it up # and sort through it later if you'd like to compare # students' scores. This will be generated by the # program. All you really need to do is remember # its name so you know what to look for. # This is generated automatically by quiztest.cgi as of QuizTest v3.0 $results_database = "$basedir/$lessondir/results.data"; # WHEW! Glad that's over! Now let's get into the program itself. # First, we will spit out some debugging info in case people are # having problems with the script. The filenames can be a problem, so # let's make sure that everything is readable, writable, and where we # expect it to be. :) You won't see this unless you've set "$debuggin +g = 1" # earlier, but it should be very helpful if you need it. &debug("I'm checking your base directory \"$basedir\"..."); # Check to see if $basedir is really a directory... if(-d $basedir){ &debug("Good: \$basedir ($basedir) is really a directory."); } else { &debug("Uh oh, I couldn't find that directory. Are you sure it exis +ts?"); } # We don't need sendmail if we're not using windows... if($opsys ne "win"){ &debug("Okay. You said sendmail is in \"$path_to_sendmail\". Checking +..."); if(-x $path_to_sendmail){ &debug("Looks like that might work. At least, $path_to_sendmail exi +sts and appears to be some sort of program."); } else { &debug("Whoops, it looks like I can't use that sendmail. (Either it doesn't exist, or is not executable, meaning I can't run it. Check +with your system administrator and make sure you're pointing to the righ +t one. If your server is Windows-based, and you're getting this message, t +hen you haven't set up this script correctly for Windows-based operatio +n. No external email program is used by this script under Windows. Not + Blat, not Cdonts, not sendmail, nothing. Under Windows, we connect direct +ly to a mail server to send mail."); } } if($data{'remote_debug'}){ $rdebug = $data{'remote_debug'};} else { $r +debug = 0; } if($data{'admlogin'}){ $admlogin = $data{'admlogin'};} else { $admlogi +n = ""; } if($data{'admpass'}){ $admpass = $data{'admpass'};} else { $admpass = +""; } my $admformtop = " <form name=QTAdmin method=POST action=$cgi_url> <input type=hidden name=remote_debug value=\"$rdebug\"> <input type=hidden name=admlogin value=\"$admlogin\"> <input type=hidden name=admpass value=\"$admpass\"> "; # Well, that should do for debugging. Now, on to the program. # # $data{'FA'} is just what we use to keep track of what commands # we want the program to do. To make the buttons look nice, sometimes # we add spaces before and behind the words, so we need to get rid # of those first. $data{'FA'} =~ s/^\s+(.*?)\s+$/$1/g; # If you remove this link, without replacing it with a similar # HTML comment (as above in the License section) you are in violation # of the license for this program. No, I don't have the resources to # enforce this, and I know that some people will remove it anyway. # But honestly, since you didn't have to pay for this, is the link # really too much to ask? :) $footer = "<br><font size=-2> <a href=\"http://www.tesol.net/scripts/\">Powered by QuizTest v3.0.31</a></font><br> $footer" if $footer !~ /tesol.net\/scripts/is; # We sometimes save results so we can mail them to the person. # This is so that someone can't arbitrarily send any message using # this program. In case the students decide not to mail the results, # that leaves all these temporary files lying around, so let's check # and delete any of them that are over 10 minutes old. opendir(DIR, "$basedir"); @mres = readdir(DIR); closedir(DIR); foreach $file (@mres){ unless(-f $file){ next; } if($file !~ /^mresults\.\d+$/){next;} my ($mresults,$timestamp) = split(/\./, $file); $timestamp =~ s/\D+//g; # Remove any of these files that are over 10 minutes (600 seconds) +old. if(-f "$basedir/$file" && $mresults eq "mresults" && time - $timestamp > 600){ # Make sure the file is "mresults.12345679" or similar. $file =~ /^(mresults\.\d+)$/; $file = $1; unlink("$basedir/$file"); } } # Get the header/footer for the quiz if there is one if(-f "$basedir/$lessondir/header"){ undef $/; open(HEADER, "<$basedir/$lessondir/header"); if($opsys ne "unix"){ binmode(HEADER); } $header = <HEADER>; close(HEADER); $/ = "\n"; } if(-f "$basedir/$lessondir/footer"){ undef $/; open(FOOTER, "<$basedir/$lessondir/footer"); if($opsys ne "unix"){ binmode(FOOTER); } $footer = <FOOTER>; close(FOOTER); $/ = "\n"; } # If you're calling this script as http://whatever/quiztest.cgi?someth +ing # then make sure "something" matches the admin password, and show the # quiz generation screen if it does. my($query_string) = ""; $query_string = $ENV{'QUERY_STRING'} or $query_string = " "; if($query_string eq "admin" || $data{'method'} eq "admin"){ &admin_login; exit(); } # Only the quiz generation screens will send a value for $data{'formac +tion'} # so we check to see what we're supposed to be doing, whether it's sho +wing # the first form, elsif($data{'FA'} eq "Log In"){ &check_auth; &show_menu; exit(); } elsif($data{'FA'} eq "MailResults"){ &mail_student_results; exit(); } elsif($data{'FA'} eq "Add Quiz"){ &check_auth; &create_quiz_one; exit(); } elsif($data{'FA'} eq "ShowForm"){ &check_auth; &showform; exit(); } # or actually creating the quiz and all associated files. elsif($data{'formaction'} eq "CreateQuiz"){ &check_auth; &createquiz; exit(); } elsif($data{'formaction'} eq "ConfigQuiz"){ &check_auth; &config_quiz; exit(); } elsif($data{'FA'} eq "Copy Quiz"){ &check_auth; &copy_quiz; exit(); } elsif($data{'FA'} eq "Delete Quiz"){ &check_auth; &deletequiz; exit(); } elsif ($data{'FA'} eq "Add Student") { &check_auth; &add_student; exit(); } elsif ($data{'FA'} eq "Edit Student") { &check_auth; &edit_student; exit(); } elsif ($data{'FA'} eq "Delete Student") { &check_auth; &delete_student; exit(); } elsif ($data{'FA'} eq "Add Instructor") { &check_auth; &add_instructor; exit(); } elsif ($data{'FA'} eq "Edit Instructor") { &check_auth; &edit_instructor; exit(); } elsif ($data{'FA'} eq "Delete Instructor") { &check_auth; &delete_instructor; exit(); } elsif($data{'FA'} eq "Get Statistics"){ &check_auth; &results_stats; exit(); } elsif ($data{'FA'} eq "View/Edit/Delete Results" || $data{'FA'} eq "View Results") { &check_auth; &view_results; exit(); } elsif ($data{'FA'} eq "Delete Results") { &check_auth; &delete_results; exit(); } elsif ($data{'FA'} eq "Edit Results") { &check_auth; &edit_results; exit(); } elsif ($data{'FA'} eq "Edit Quiz") { &check_auth; &edit_quiz; exit(); } elsif ($data{'FA'} eq "Reset Quiz") { &check_auth; &reset_quiz; exit(); } elsif ($data{'FA'} eq "ExportToAscii") { &check_auth; &export; exit(); } elsif ($data{'FA'} eq "View Quiz") { &check_auth; &view_quiz; exit(); } # If there are no admin things to do, we'll just assume that someone # was taking the quiz and try to find something to grade. elsif ($data{'FA'} eq "Grade Quiz") { &grade_quiz; exit(); } elsif ($data{'FA'} eq "ShowScores") { &show_high_scores_only; exit(); } elsif($ENV{'QUERY_STRING'} ne ""){ &show_quiz } else { &no_args_error; exit(); } sub no_args_error { if($error eq ""){ $error = "<br><br> Welcome! Please choose from one of the links below:"; } print "$header <b>$error</b><br><br> <b>Quizzes:</b><br><br>"; open(F, "<$instructors_file") || &debug("Could not open instructors file: $! (This may be okay if y +ou have not yet set up any quizzes.)"); if($opsys eq "win"){ $winline = "<th>Scores</th>"; } print "<table border=1><tr><th>Quiz</th>$winline<th>Instructor</th +></tr>\n"; foreach $line (<F>){ ($id,$pw,$name,$quizname) = split(/\|/, $line); @quizzes = sort({lc($a) cmp lc($b)} split(/%/,$quizname)); if($id ne ""){ foreach $quiz (@quizzes){ $quiz =~ s/\s+$//sg; if($lastquiz eq $quiz){ next; } $q2 = $quiz; $q2 =~ tr/[A-Z]/[a-z]/; $q2 =~ s/\W+/ +/g; if($remote_debugging eq "on" && $data{'debugging'} == + 1){ $remdbg = "&debugging=1"; } if($show_scores_for_all_quizzes eq "Yes"){ if($opsys eq "win"){ $high_scores_ln = "<form method=\"POST\" action=\" +$cgi_url\"> <td> <input type=\"hidden\" name=\"FA\" value=\"ShowSco +res\"> <input type=\"hidden\" name=\"Quiz\" value=\"$q2\" +> <input type=\"submit\" value=\"Scores\"> + </td> </form>"; } else { $high_scores_ln = " (<a href=$cgi_url?FA +=ShowScores&Quiz=$q2>Scores</a>)"; } } $quiz = repipe($quiz); $quiz = unpipe_for_html($quiz); if($opsys eq "win"){ print "<form method=\"POST\" action=\"$cgi_url\"> <input type=\"hidden\" name=\"method\" value=\" +$q2\"> <tr><td><input type=\"submit\" style=\"width: 2 +5em\" value=\"$quiz\"></td></form>$high_scores_ln<td>($name)</td></tr +>" if($q2 ne "" && $quiz !~ /Another Sample Quiz/i); } else { print "<tr> <td><a href=$cgi_url?$q2$remdbg>$quiz</a> $high_scores_ln</td><td>($name)</td></tr>" if($q2 ne "" && $quiz !~ /Another Sample Quiz/i); } $foundquiz = 1 if($q2 ne ""); $lastquiz = $quiz; } # end foreach $quiz } # end if($id ne "") } close(F); if($foundquiz != 1){ print "<tr><td colspan=2>(No Quizzes Found)</t +d></tr>";} if($remote_debugging eq "on" && $data{'debugging'} == 1){ $remdbg = "&debugging=1"; } print "</table><br><br>"; if($opsys eq "win"){ print "<form method=\"POST\" action=\"$cgi_url\"> <input type=\"hidden\" name=\"method\" value=\"admin\"> <input type=\"submit\" value=\"QuizTest Administration\"> </form>"; } else { print "<a href=$cgi_url?admin$remdbg>QuizTest Administration</a> +"; } print "$footer"; exit(); } sub edit_quiz { $html = &find_quizzes("option"); $qstudents = &get_students_as_checkboxes(&unpipe($data{'Quiz'})); if($data{'FA2'} eq "Show"){ if($data{'Quiz'} =~ /NO QUIZZES FOUND/ || $data{'Quiz'} eq ""){ print "$header <b>Error: No quizzes found.</b> $footer"; exit(); } $quiz = &repipe($data{'Quiz'}); $quiz =~ tr/[A-Z]/[a-z]/; $quiz =~ s/\W+//g; unless(-d "$basedir/$quiz"){ $quiz = unpipe($data{'Quiz'}); $quiz =~ tr/[A-Z]/[a-z]/; $quiz =~ s/\W+//g; } $quizfile = "$basedir/$quiz/quizdb"; unless(-f "$quizfile"){ $quiz = repipe($data{'Quiz'}); $quiz = unpipe_for_html($quiz); $message = "<b>Error: quiz $quiz not found.</b>"; $data{'FA2'} = ""; &edit_quiz; exit(); } open(FILE, "<$quizfile") || &debug("Could not open $quizfile: $!"); if($opsys ne "unix"){binmode(FILE);} ($title,$instr,$fn,$ea,$id,@qs) = split(/\|/, <FILE>); close(FILE); $title = &repipe($title); $oldtitle = &unpipe_for_html($title); $quizdir = $title; $quizdir =~ tr/[A-Z]/[a-z]/; $quizdir =~ s/\W+//g; $fn = repipe($fn); $hfn = unpipe_for_html($fn); $ea = repipe($ea); $hea = unpipe_for_html($ea); $id = repipe($id); $hid = unpipe_for_html($id); unless(-d "$basedir/$quizdir"){ $quizdir = unpipe($title); $quizdir =~ tr/[A-Z]/[a-z]/; $quizdir =~ s/\W+//g; } if(-f "$basedir/$quizdir/header"){ undef $/; open(F, "<$basedir/$quizdir/header") || &debug("Could not open quiz header file $basedir/$quizdir/heade +r: $!"); if($opsys ne "unix"){binmode(F);} $qheader = <F>; close(F); $/ = "\n"; } if(-f "$basedir/$quizdir/footer"){ undef $/; open(F, "<$basedir/$quizdir/footer") || &debug("Could not open quiz footer file $basedir/$quizdir/foote +r: $!"); if($opsys ne "unix"){binmode(F);} $qfooter = <F>; close(F); $/ = "\n"; } if(-f "$basedir/$quizdir/endmessage"){ undef $/; open(F, "<$basedir/$quizdir/endmessage") || &debug("Could not open end-of-quiz message file $basedir/$quizd +ir/endmessage: $!"); if($opsys ne "unix"){binmode(F);} $endmessage = <F>; close(F); $/ = "\n"; } else { $endmessage = "<br>\nThank you for taking the quiz.\n<br>\n<br>\n" +; $endmessage .= "You may now\n"; $endmessage .= "<a href=\"$cgi_url\">Return to the main Quiz page +></a>\n"; $endmessage .= "<br>\n"; } $qheader = repipe($qheader); $qheader = unpipe_for_html($qheader); $qfooter = repipe($qfooter); $qfooter = unpipe_for_html($qfooter); $instr = repipe($instr); $instr = unpipe_for_html($instr); $endmessage = repipe($endmessage); $endmessage = unpipe_for_html($e +ndmessage); print "$header <br> $admformtop <b>Instructions for Quiz Editing:</b> You may edit any porti +on of the quiz by replacing the existing text with any changes or additions you would like to make. NOTE: You may not change the title of the quiz, but anything else may be modified. To edit a question or answer, simply change the text in those fields. To delete a question, simply clear out the text box with that question. You may add a question using the blank question/answe +r fields at the bottom. Or, click the <b>Copy Quiz</b> button to copy this quiz and/or assign it to a different instructor. <input type=hidden name=FA value=\"Copy Quiz\"> <input type=hidden name=OldTitle value=\"$oldtitle\"> <input type=submit value=\"Copy Quiz\"><br> </form> <hr> $admformtop <table border=0> <tr><th align=center colspan=2> Title Of this quiz: \"$title\" (Sorry, Quiz Titles may not be changed.)</th> </tr> <tr><td align=center colspan=2 bgcolor=\"#E4D8E2\"> <b>If you'd like any custom HTML code to be printed at the top of each quiz page, enter it here</b> </td></tr> <tr><td colspan=2 align=center> <textarea wrap=soft name=Header rows=3 cols=60>$qheader</textarea> +</td></tr> <tr><td align=center colspan=2 bgcolor=\"#E4D8E2\"> <b>If you'd like any custom HTML code to be printed at the bottom of each quiz page, enter it here< +/b> </td></tr> <tr><td colspan=2 align=center> <textarea wrap=soft name=Footer rows=3 cols=60>$qfooter</textarea> +</td></tr> <tr><th align=center colspan=2 bgcolor=\"#E4D8E2\"> <b>Please enter instructions for the quiz takers.</b></b></th></tr> <tr><td colspan=2> In the area below, enter any instructions or other text which you would like to have appear at the top of the page for this quiz.</td></tr> <tr> <th colspan=2><textarea name=instr rows=5 cols=60 wrap=soft>$ins +tr</textarea> </th> </tr> <tr><td align=center bgcolor=\"#E4D8E2\" colspan=2> <b>If you'd like a specific message to be shown after the quiz, you may enter it here. This can include a link to the home page, links to the lesson pages, a \"Thank you for taking the quiz\" message, etc.</b> </td></tr> <tr><td colspan=2 align=center> <textarea wrap=soft name=EndMessage rows=5 cols=60>$endmessage</textar +ea></td></tr> <tr><th align=center colspan=2 bgcolor=\"#E4D8E2\"> <b>Modify the form fields</b></th></tr> <tr><td colspan=2> Each quiz has three blanks for the user to fill in. By default, these are \"Full Name,\" \"Email Address,\" and \"ID Number\". Here, you will see the default messages that will appear on the quiz form for each quiz. If you would like different messages to appear, please take out what is below, and enter your own messages. HINT: If you are us +ing the \"authorized users\" feature, you may blank these out, and t +he program will use the values from the student databases instead. </td></tr> <tr><td colspan=2 align=center> <table border=0> <tr><th>Name</th><th>Email</th><th>ID</th></tr> <tr> <td><input type=text name=fn value=\"$hfn\" size=30></td> <td><input type=text name=ea value=\"$hea\"></td> <td><input type=text name=id value=\"$hid\" size=29></td> </tr> </table> </td></tr> <tr><th align=center colspan=2 bgcolor=\"#E4D8E2\"> <b>Quiz and Quiz Takers</b> </th></tr> <tr><td colspan=3> On the left, enter the questions and the possible answers. Hint: To enter a Short-Answer question, type the question as usu +al, but make sure to select the check box for whether you want stude +nts to see a single-line text field or a multi-line text field for filling in their answer. <br><br> To give multiple options for a Short-Answer field, separate the options with two forward slashes (//), e.g.: \"Yes//Yep//Yeah//Yessir\". Be sure to mark it as correct. If you are using the \"authorized users\" function, select or un +select the checkboxes next to the students who are allowed to take this qui +z. <hr> </td></tr> <tr><th>QuestionsAnswers</th> <th>Authorized Students $select_all_students_html </th></tr> <tr><td valign=top> <table border=0> <tr><th rowspan=2>Question</th><th rowspan=2>Possible Answers</ +th> <th colspan=3>Short-answer questions</th></tr> <tr> <th><font size=2>Multiple Choice</font></th> <th><font size=2>Single-line text field</font></th> <th><font size=2>Multi-line text field</font></th></tr>"; foreach $q (@qs){ $i++; $j=0; #($ques,$ans) = split(/ # /, $q); ($ques,$ans) = split(/#/, $q); # get the original correct answers open(AF, "<$basedir/$quizdir/answerfile"); @realanswers = grep(/^\d+/, <AF>); close(AF); $ques =~ s/\"/&quot;/g; $ques =~ s/KPHHASH/#/g; #$ques = &repipe($ques); print "<tr><th valign=top><b>$i.</b> <input type=text name=$i-q value=\"$ques\"></th> <td><table border=0>"; $ans = &repipe($ans); # Allow people to un-choose short-answer if necessary. # 02-29-04 if($ans =~ /%SAT%/){ $satck = " CHECKED"; $saqck = ""; $sarck = + ""; $ans =~ s/%SAT%//; } elsif($ans =~ /%SAQ%/){ $saqck = " CHECKED"; $satck = ""; $sarc +k = ""; $ans =~ s/%SAQ%//; } else{ $sarck = " CHECKED"; $satck = ""; $saqck = "";} foreach $a (split(/%%/, $ans)){ my ($n,$t) = split(/\|/, $realanswers[$i - 1]); $a =~ s/\s+$//; $a =~ s/^\s+//; $t =~ s/\s+$//; $t =~ s/^\s+//; #if($ENV{'REMOTE_ADDR'} eq "207.228.46.235"){ # print "\nDEBUG: a '$a'\n t '$t'\n<br>"; # print "\nDEBUG: repipe_a '" . &repipe($a) . "'\n repipe_t + '" . &repipe($t) . "'\n<br>"; # } if($a eq $t || ($a eq "" && $t ne "") || &repipe($t) eq $a) +{ $ck = " CHECKED"; } $j++; if($a eq ""){$a = $t;} $a =~ s/\"/&quot;/g; $a =~ s/KPHHASH/#/g; print "<tr><td><input type=text name=$i-$j-a value=\"$a +\"></td> <td><input type=radio name=\"$i-c\" value=\"$i-$j-a\"$ck +></td><td>(Correct)</td></tr>"; $ck = ""; $numqedit++; } $n = $numqedit + 1; $newanswer = $j + 1; print "<tr><td><input type=text name=$i-$newanswer-a valu +e=\"$a\"></td> <td><input type=radio name=\"$i-c\" value=\"$i-$newans +wer-a\"$ck></td> <td>(Correct)</td></tr></table>"; print "</td> <th valign=top><input type=radio name=SA-$i value=\"\"$sarck +></th> <th valign=top><input type=radio name=SA-$i value=\"SAQ\"$sa +qck></th> <th valign=top><input type=radio name=SA-$i value=\"SAT\"$sa +tck></th></tr> <tr><td colspan=2><hr></td></tr>\n"; } # Maybe let them add one more question... $i++; $j=0; $saqck = ""; $satck = ""; $sarck = " CHECKED"; print "<tr><th valign=top><b>$i.</b> <input type=text name=$i-q value=\"\"></th> <td>"; for($j = 1; $j < 8; $j++){ print "<input type=text name=$i-$j-a value=\"\"> <input type=radio name=\"$i-c\" value=\"$i-$j-a\"$ck> (Correct)<br>"; } print "</td> <th valign=top><input type=radio name=SA-$i value=\"\" CHECKE +D></th> <th valign=top><input type=radio name=SA-$i value=\"SAQ\"$saq +ck></th> <th valign=top><input type=radio name=SA-$i value=\"SAT\"$sat +ck></th></tr> </table>\n</td><td valign=top>$qstudents</td></tr>\n"; $qtitle = unpipe_for_html($title); print "<tr><td colspan=2><input type=hidden name=qtitle value=\" +$qtitle\"> <input type=hidden name=FA value=\"Edit Quiz\"> <input type=hidden name=numquestions value=\"$i\"> <input type=submit name=FA2 value=\"Edit Configuration\"> </td></tr> </table></form> $footer"; exit(); } elsif($data{'FA2'} eq "Edit Configuration"){ print "$header"; $quizdir = &unpipe($data{'qtitle'}); $quizdir =~ tr/[A-Z]/[a-z]/; $quizdir =~ s/\W+//g; print &quiz_options_form("$basedir/$quizdir/config"); foreach $key (keys(%data)){ if($key ne "formaction" && $key ne "admlogin" && $key ne "admpa +ss" && $key ne "FA" && $key ne "FA2" && $key ne "Student"){ $pval = &unpipe_for_html($data{$key}); print "<input type=hidden name=\"$key\" value=\"$pval\">\n"; } } @stu = split(/\0/, $data{'Student'}); foreach $stu (@stu){ print "<input type=hidden name=Student value=\"$stu\">\n"; } print "<input type=hidden name=FA value=\"Edit Quiz\"> <input type=submit name=FA2 value=\"Make Changes\"> </form> $footer"; exit(); } elsif($data{'FA2'} eq "Make Changes"){ foreach $key (keys(%data)){$data{$key} = &repipe($data{$key});} $num = $data{'numquestions'}; $title = &unpipe($data{'qtitle'}); $fn = &unpipe($data{'fn'}); $ea = &unpipe($data{'ea'}); $id = &unpipe($data{'id'}); $instr = &unpipe($data{'instr'}); @qstudents = split(/\0/, $data{'Student'}); if($qstudents[0] eq ""){ $qstudents[0] = $data{'Student'}; } # Add this quiz to any student who doesn't already # have it. &add_quiz_to_students($title,@qstudents); # Get rid of newlines if any $instr =~ s/\r\n/ /g; $instr =~ s/\n/ /g; $quizdir = $data{'qtitle'}; $quizdir =~ tr/[A-Z]/[a-z]/; $quizdir = +~ s/\W+//g; unless(-d "$basedir/$quizdir"){ $quizdir = unpipe($data{'qtitle'}); $quizdir =~ tr/[A-Z]/[a-z]/; $quizdir =~ s/\W+//g; } # Set up the header/footer if any if($data{'Header'} ne ""){ open(F, ">$basedir/$quizdir/header") || &debug("could not open he +ader $!"); $data{'Header'} =~ s/\r\n/\n/g; $data{'Header'} =~ s/\n+/\n/g; if($opsys ne "unix"){binmode(F);} print F "$data{'Header'}"; close(F); } else { if(-f "$basedir/$quizdir/header"){unlink("$basedir/$quizdir/header +");} } if($data{'EndMessage'} ne ""){ open(F, ">$basedir/$quizdir/endmessage") ||

Replies are listed 'Best First'.
Re: Break HTML table output into two or three columns
by davido (Cardinal) on Feb 13, 2017 at 18:47 UTC

    The code you posted was truncated at line 1510, probably because it exceeded the 64kb limit for posts here at PerlMonks.

    This limit exists for both technical and social reasons. But most important in your case are the social reasons. The fact is you are not going to get someone to devote a bunch of time for free, to read through more than 1500 lines of code when the purpose of this site is to help people learn to be effective with Perl. The site doesn't exist to facilitate free coding for people in need who aren't interested in learning Perl.

    One step toward getting good answers is to read Writeup Formatting Tips, which apparently you have done, as your post is well formatted. There is also the principle of making the title of your post brief, and to the point. And then there is the all important Short Self-Contained Correct/Compilable Example, which you have not come close to doing. This is absolutely vital -- We need to see exactly the part of the problem you cannot solve yourself. We often also need to see the smallest useful data set that produces the problem you are encountering, and an example of the expected result. If "the whole thing" is the part of the problem you cannot solve yourself, you should be seeking someone who will take on your project for you, and that often involves pay.


    Dave

Re: I need to add a code snippet ... TL;DR
by LanX (Saint) on Feb 13, 2017 at 18:17 UTC
Re: Break HTML table output into two or three columns
by 1nickt (Canon) on Feb 13, 2017 at 18:38 UTC

    "However, the Perl is absolutely beyond me. As you know, Perl is very speedy, but breaks very easily, so I am not even going to try ... I know nothing of Perl"

    It looks like you are in need of a Perl contractor. You can post a job description (for free) at jobs.perl.org.

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Break HTML table output into two or three columns
by GotToBTru (Prior) on Feb 13, 2017 at 19:27 UTC

    Questions to assist you (and us!):

    1. Have you identified the code that produces the single column of output?
    2. Can you provide an example of this output?
    3. Can you provide the output as you wish to see it?
    4. Can you explain when there should be 3 columns instead of 2?
    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Re: Break HTML table output into two or three columns
by AnomalousMonk (Archbishop) on Feb 13, 2017 at 23:45 UTC
    I need to add a code snippet ... that will break the output of the multiple choice table into two, or preferably three columns.

    You don't give any indication of acceptable formatting and I'm not inclined to plow through the wall of code to find the "output of the multiple choice table", but maybe something like this will serve. Examples are generated for many different numbers of items, but only a few are shown here.

    c:\@Work\Perl\monks>perl -wMstrict -le "my @things = qw( zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen ); ;; use constant COLS => 3; use constant FMT => '%10s ' x COLS; ;; for my $max (0 .. $#things) { my @stuff = @things[0 .. $max]; my $k = @stuff / COLS; $k = int($k + 1) if int($k) != $k; ;; my @rows; $rows[$_ % $k][$_ / $k] = $stuff[$_] for 0 .. $#stuff; ;; for my $ar_row (@rows) { printf qq{${ \FMT }\n}, @$ar_row, ('') x COLS; } print '--------------'; } "
    Output:
    zero -------------- zero one -------------- zero one two -------------- zero two one three -------------- zero two four one three -------------- zero two four one three five -------------- zero three six one four two five -------------- ... ... -------------- zero six twelve one seven thirteen two eight fourteen three nine fifteen four ten five eleven -------------- zero six twelve one seven thirteen two eight fourteen three nine fifteen four ten sixteen five eleven -------------- zero six twelve one seven thirteen two eight fourteen three nine fifteen four ten sixteen five eleven seventeen --------------

    ... I can make a donation, but not a great one.

    Yes, any donation, however small, is most welcome — and thank you in advance!


    Give a man a fish:  <%-{-{-{-<

Re: Break HTML table output into two or three columns
by poj (Abbot) on Feb 14, 2017 at 07:51 UTC

    Do you want to change it both for when the quiz is set up i.e. on the admin page AND on the page the student sees ?.That would be here

    ANS: # line 2649 foreach $ans (@ans){ $ans =~ s/^\s+//g; $ans =~ s/\s+$//g; $ans2 = &repipe($ans); if($ans ne "" && $ans2 =~ /^%SAQ%/){ print "<input type=text name=$num value=\"$data{$num}\"><br>\n"; last ANS; } elsif($ans ne "" && $ans2 =~ /^%SAT%/){ print "<textarea name=$num rows=5 cols=40>$data{$num}</textarea>< +br>\n"; last ANS } elsif($ans ne "") { if($esc_num eq $ans){ $ck = " CHECKED";} else{ $ck = ""; } print "<input type=radio name=$num value=\"$ans\"$ck>$ans2<br>\n"; } }
    poj
      Hi,

      Well, I think the best course of action would be to offer you fifty dollars to post a working version of the script. That way, there is no possibility that some slight difference in the way your server and my server handles the script is at fault where breaking is concerned.

      I can find the exact line-number, and recognize all sorts of things that might break the script, such as smart quotes and binary uploads, and even things I can't verbalize, but I can't tell if the code is actually going to pass through Site5 anti-hacking filters. If you want to try it on your server, that's fine; if you want to try it on my server, I will make you a folder to work in. Thank you, again!

      Jagtig

        As far as I can see there are 3 places that need editing. The 'edit' page that you identified around lines 1370-1423 (54 lines) but also the 'add' page at lines 3658-3679 (22 lines) and the 'view' page at 2650-2666 (17 lines). The question was do you want to change all these pages or just the view. The view page is relatively simple and with a little guidance you should be able to do that yourself.

        poj

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1181910]
Approved by beech
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-04-19 22:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found