So I've been teaching my self how to code C++ I purchased the book Beginning C++ through game programming, third edition by Michael Dawson and in it is a chapter you learn about loops. Towards the end of the chapter you make a game that jumbles a word. I wanted to go a little further with it and made 5 words that it picks at random. The problem is though, it always gets a value of 5, and therefore always selects the fifth word.
The code is as follows below
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
enum fields {WORD, HINT, NUM_FIELDS};
const int NUM_WORDS = 5;
const string WORDS[NUM_WORDS][NUM_FIELDS] =
{
{"wall", "Do you feel you're banging your head against something?"},
{"glasses", "These might help you see the answer"},
{"labored", "Going slowly is it?"},
{"persistent", "Keep at it"},
{"jumble", "It's what this game is about!"}
};
srand(time(0));
int preWord = rand() % 3;
string tempWord;
string theWord = WORDS[preWord][WORD]; //word to guess
string theHint = WORDS[preWord][HINT]; //hint for word
if (preWord = 1)
{
theWord = "wall";
tempWord = "wall";
}
if (preWord = 2)
{
theWord = "glasses";
tempWord = "glasses";
}
if (preWord = 3)
{
theWord = "labored";
tempWord = "labored";
}
if (preWord = 4)
{
theWord = "persistent";
tempWord = "persistent";
}
if (preWord = 5)
{
theWord = "jumble";
tempWord = "jumble";
}
int length = theWord.size();
for (int i = 0; i < length; ++i)
{
int index1 = (rand() % length);
int index2 = (rand() % length);
char temp = theWord[index1];
theWord[index1] = theWord[index2];
theWord[index2] = temp;
}
cout << "\t\t\tWelcome to the Word Jumble!\n\n";
cout << "Unscramble the letters to make a word.\n";
cout << "Enter 'hint' for a hint.\n";
cout << "Enter 'quit' to quit the game.\n\n";
cout << "The word is: " << theWord;
cout << "\nvariable 'preWord' is: " << preWord;
string guess;
cout << "\n\nYour guess: ";
cin >> guess;
while ((guess != tempWord) && (guess != "quit"))
{
if (guess == "hint")
{
cout << theHint;
}
else
{
cout << "Sorry, that's not it.";
}
cout <<"\n\nYour guess: ";
cin >> guess;
}
if (guess == tempWord)
{
cout << "\nThat's it! You guessed it!\n";
}
cout << "\nThanks for playing!\n";
return 0;
}
In your conditions, you should write :
if (preWord == x)
which is a comparison, and not
if (preWord = 5)
which is an assignment - which means, when your code reach each of those if statements, it will actually ASSIGN the value to your variable - and since your 5th case if the last, it will ultimately change the value of preWord to 5.
You are setting preWord to 5. if (preWord = 5) not checking its equality. It should be if (preWord == 5). Compile with warnings on and you should never have this problem.
As others have pointed out you are using the assignment operator(=) in your if statements as opposed to the equality operator(==) and therefore you are setting the value of preWord at ech if statement:
if (preWord = 5)
^
Should be:
if (preWord == 5)
^^
A habit I have gotten into is to put the literal on the other side of the equality like so:
if ( 5 == preWord )
If you had used = instead, it would be an outright error, in gcc you would see this message:
error: lvalue required as left operand of assignment
Of course turning on warning is always important and even if you used the form in your code you would have seen the following warning from gcc:
warning: suggest parentheses around assignment used as truth value
= is assignment and == is comparison. so all your ifs need to use ==...so change them as if (preWord == 4)
also, int preWord = rand() % 3; will generate random numbers in the range of 0 to 2. you need to use int preWord = rand() % 5 +1 for generating numbers in the range of 1 to 5
Related
I've been struggling with a homework assignment that counts the amount of instances a uppercase letters, lowercase letters, and numbers in a string. appears in a string.
I'm using a one-dimensional array with a constant size of 132 to store the entered string, and I need to use two functions. One needs to count the amount of letter occurrences in the string and the other function will execute the output something similar to above. I'm struggling most with the letter counting aspect of the program itself.
Currently, this is what my current homework resembles for the most part. It's a work in progress (of course) so errors in the code are very likely.
void LetterCount(char c_input[], int l_count)
{
// code to count letters
}
void CountOut(//not sure what should go here yet until counting gets figured out)
{
// code that handles output
}
int main()
{
const int SIZE = 132;
char CharInput[SIZE];
int LetterCount = 0;
cout << "Enter a string of up to 132 characters in size: ";
cin.getline(CharInput, SIZE);
cout << "You entered: " << CharInput << endl;
Count(CharInput);
CountOut(//not sure what goes here yet);
return 0;
}
The output would look something like:
a - 2
b - 1
c - 1
d - 0
e - 1
etc...
I've tried some experimentation with for loops to count the letters and have seen some examples of the function gcount(), but I haven't gotten anything to work. Does anyone have a suggestion as to how I would count the letters in an inputted string?
map is a very efficient data structure here
#include <iostream>
#include <map>
using namespace std;
int main(){
string str = "a boy caught 2 fireflies";
map<char, int> str_map;
for(auto x : str) ++str_map[x];
for(auto x : str_map) cout << x.first << ' ' << x.second << '\n';
}
What you want is to build a simple histogram, and it's pretty easy to do. Since what you're looking at is chars, and there can be 256 possible values of an 8-bit char (in practice your input string probably uses less, but we'll be conservative here because memory is cheap), you'll want to start with an array of 256 ints, all of them initialized to zero. Then iterate over the chars your string, and for each char in your string, use that char-value as an offset into the array(*), and simply increment that item in the array.
When you're done, all that remains is to iterate over the ints in the array and print out the ones that are non-zero, and you're done.
(*) you may want to cast the char to unsigned char before using it as an offset into the array, just to avoid any chance of it being interpreted as a negative array-index, which would result in undefined behavior (this is only an issue if your input string contains ASCII characters 128 and higher, so it may not matter in your case, but it's always good form to make code that does the right thing in all cases if you can)
As Jeremy frisner said you're building a histogram, but I disagree with the types used.
You'll want to declare your histogram like so:
size_t histogram[sizeof(char)*CHAR_BIT] = {0};
The size_t because you might overflow without it, and you need enough space if it's a nonstandard byte size.
As for printing it out. You should take a look at an ASCII table and examine which values you need to print out.
You could do it by comparing c-strings with other c-strings. But with chars and strings you can get errors like: "const *char cant be compared with strings". So you'll have to compare each c string(array) index with other c string indexes. In this program I use if statements to look for certain vowels. The way it works is that each "string alphabet_letter" is equal to it's respective lowercase and capital letters (for comparison). this is a very redundant way to do it and, if you want to count all total letters, perhaps you should try a different way, but this method doesn't use very complicated methods that require deeper understanding.
using namespace std;
int main(){
int vowel;
string A = "aA";
string E = "eE";
string I = "iI";
string O = "oO";
string U = "uU";
string str;
string str1;
bool userLength = true;
int restart = 0;
do{
cout << "Enter a string." <<endl;
getline(cin, str);
int VowelA = 0;
int VowelE = 0;
int VowelI = 0;
int VowelO = 0;
int VowelU = 0;
for(int x = 0; x < 100; x++){
if(restart == 1){
restart = 0;
x = 0;
}
if(A[0] == str[x]){
VowelA = VowelA + 1;
}
if(E[0] == str[x]){
VowelE = VowelE + 1;
}
if(I[0] == str[x]){
VowelI = VowelI + 1;
}
if(O[0] == str[x]){
VowelO = VowelO + 1;
}
if(U[0] == str[x]){
VowelU = VowelU + 1;
}
if(A[1] == str[x]){
VowelA = VowelA + 1;
}
if(E[1] == str[x]){
VowelE = VowelE + 1;
}
if(I[1] == str[x]){
VowelI = VowelI + 1;
}
if(O[1] == str[x]){
VowelO = VowelO + 1;
}
if(U[1] == str[x]){
VowelU = VowelU + 1;
}
int strL = str.length();
if(x == strL){
cout << "The original string is: " << str << endl;
cout << "Vowel A: "<< VowelA << endl;
cout << "Vowel E: "<< VowelE << endl;
cout << "Vowel I: "<< VowelI << endl;
cout << "Vowel O: "<< VowelO << endl;
cout << "Vowel U: "<< VowelU << endl;
cout << " " << endl;
}
}
char choice;
cout << "Again? " << endl;
cin >> choice;
if(choice == 'n' || choice == 'N'){userLength = false;}
if(choice == 'y' || choice =='Y')
{
restart = 1; userLength = true;
cin.clear();
cin.ignore();
}
//cout << "What string?";
//cin.get(str, sizeof(str),'\n');
}while(userLength == true);
}
/*
Sources:
printf help
http://www.cplusplus.com/reference/cstdio/printf/
This helped me with the idea of what's a vowel and whats not.
http://www.cplusplus.com/forum/general/71805/
understanding gets()
https://www.programiz.com/cpp-programming/library-function/cstdio/gets
Very important functional part of my program...Logic behind my if statements, fixed my issues with string comparison
What i needed to do was compare each part of one cstring with another c string
strstr compares two strings to see if they are alike to one another this source includes that idea-> https://www.youtube.com/watch?v=hGrKX0edRFg
so I got the idea: What is one c string was all e's, I could then compare each index for similarities with a c string whos definition was all e's.
At this point, why not just go back to standard comparison with strings? But you cant compare const chars to regular chars, so I needed to compare const chars to const chars
hence the idea sparked about the c strings that contained both e and E.
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
Fixed Error with using incremented numbers outside of involved forloop.
https://stackoverflow.com/questions/24117264/error-name-lookup-of-i-changed-for-iso-for-scoping-fpermissive
understanding the use of getline(cin, str_name)
https://stackoverflow.com/questions/5882872/reading-a-full-line-of-input
http://www.cplusplus.com/reference/istream/istream/getline/
http://www.cplusplus.com/forum/beginner/45169/
cin.clear - cin.ignore --fixing issue with cin buffer not accepting new input.
https://stackoverflow.com/questions/46204672/getlinecin-string-not-giving-expected-output
*/
I am brand new to C++, and am trying to make a simple program to determine if a user-entered integer is four digits, and if so, to reverse the order of said digits and print that output.
I have a (mostly) working program, but when I try, one of two things happens:
a) if line 16 is commented out and line 17 is active, then the program prints out an infinite number of reversed numbers and the IDE (in this case, repl.it) crashes; or
b) if line 17 is commented out and line 16 is active, then the program prints out one correct line, but the next line is "Your number is too short...again" (look at code below)
#include <iostream>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main() {
int n, reversedNumber, remainder;
bool loopControl;
char userFinalResponse;
reversedNumber=0;
cout<<"Input a 4 digit integer and press Return\n"<<endl;
cin>>n;
while (loopControl=true){
//if ((n>9999)||(n<1000))
if ((n>9999)||((n<1000)&&(n>0)))
{
cout<<"Your number is too short or too long. Please try again.\n"<<endl;
cin>>n;
loopControl=false;
} else {
while(n != 0)
{
remainder = n%10;
reversedNumber=reversedNumber*10+remainder;
n /= 10;
loopControl=true;
}//closing brace for reversal loop
cout<<"Your reversed number is "<<reversedNumber<<"\n"<<endl;
}//closing brace for else
}//closing brace for "while (loopControl>0){"
return 0;
}//closing brace for "int main() {"
You can try this:
int number = 1874 //or whatever you need
auto str = std::to_string(number);
if (str.length() == 4) {
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
}
I suggest you to give a look at the algorithm header that contains a lot of useful methods that can help you while developing programs.
According to the cpp tutorials = is the assignment operator, not the comparison operator. Because of this your while loop will never terminate. You can simply initialize loopControl to true, and then set it to false when it's okay to exit:
int n, reversedNumber, remainder;
bool loopControl = true; //Initialize to true
char userFinalResponse;
reversedNumber = 0;
cout << "Input a 4 digit integer and press Return\n" << endl;
cin >> n;
while (loopControl) {
//if ((n>9999)||(n<1000))
if ((n>9999) || ((n<1000) && (n>0)))
{
cout << "Your number is too short or too long. Please try again.\n" << endl;
cin >> n;
loopControl = true; //need to keep on looping
}
else {
while (n > 0)
{
remainder = n % 10;
reversedNumber = reversedNumber * 10 + remainder;
n /= 10;
loopControl = false; //Ok to exit
}//closing brace for reversal loop
cout << "Your reversed number is " << reversedNumber << "\n" << endl;
}
}
I added a while statement around my code so that the user could repeat the process as my teacher instructed, the way I did it worked on other code but for some reason it broke this one I could use help making it work please and thank you. The point of the code is to just flip 10000 coins and output the number of heads and tails. Thanks for any and all help.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
// Keaton Graffis 12/22/2012
int coin()
{
int flip;
// assign random numbers
flip = rand() % 2 + 1;
return (flip);
}
int main()
{
char choice = 'y';
while (choice == 'y' || choice == 'Y');
{
double numFlips = 10000;
int count, face, heads = 0, tails = 0;
// initialize the random number generator
srand(static_cast<int>(time(0)));
// generate and count the number of heads and tails
for (int count = 1; count <= numFlips; count++)
{
face = coin();
if (face == 1)
heads++;
else
tails++;
}
cout << "The number flips: " << numFlips << endl;
cout << "The number of heads: " << heads << endl;
cout << "The number of tails: " << tails << endl;
// Asks user if they would like to go again(makes cod enot run, not sure why, this works on all my other code)
while (1)
{
cout << "Would you like to play again [Y]es or [N]o?\n";
cin >> choice;
if (choice == 'y' || choice == 'Y' || choice == 'n' || choice == 'N')
break;
}
}
}
Remove the semicolon after the while condition of the first loop. Only full statements are terminated by a ;.
Notes:
Since C++11, better facilities for random number generation are provided in the <random> header. Use these!
Alright so I've been looking though Google and on forums for hours and can't seem to understand how to solve this problem.
I need to write a program that first determines if the number entered by the user is a base 5 number (in other words, a number that only has 0s, 1s, 2s, 3s, and 4s in it). Then, I have to count how many 0s, 1s, 2s, etc are in the number and display it to the user.
I've seen people saying I should convert int to a string and then using cin.get().
I noticed that I can't use cin.get() on a string, it needs to be a char.
I can only use a while loop for this assignment, no while... do loops.
Any help is appreciated!!
Here's what I have so far, obviously with all my mistakes in it:
//----------------------------------------------
// Assignment 3
// Question 1
// File name: q1.cpp
// Written by: Shawn Rousseau (ID: 7518455)
// For COMP 218 Section EC / Winter 2015
// Concordia University, Montreal, QC
//-----------------------------------------------
// The purpose of this program is to check if the
// number entered by the user is a base of 5
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
// Declaring variables
int number;
int zeros;
int ones;
int twos;
int threes;
int fours;
bool base5;
// Get data and calculate
cin >> number;
string numberString = to_string(number);
// Determine if the number is a base 5 number
while (cin.get(numberString) == 0 || cin.get(numberString) == 1 ||
cin.get(numberString) == 2 || cin.get(numberString) == 3 ||
cin.get(numberString) == 4)
base5 = true;
// Determine the number of each digits
zeros = 0;
ones = 0;
twos = 0;
threes = 0;
fours = 0;
return 0;
}
Several things you need to beware of:
One way to get a specific character from a std::string is by []. e.g.
std::string myString{"abcdefg"};
char myChar = myString[4]; // myChar == 'e'
cin.get(aString) is not trying to get data from aString. It continues to get data from stdin and store in aString. Once you have get the data and put into the string, you can simply manipulate the string itself.
a short piece of code that will count number of vowel in a string. If you can understand it, there should be no problem doing your work. (Haven't compiled, probably some typos)
std::string inputString;
std::cin >> inputString;
// you said you need a while loop.
// although it is easier to with for loop and iterator...
int i = 0;
int noOfVowels = 0;
while (i < inputString.length()) {
if (inputString[i] == 'a'
|| inputString[i] == 'e'
|| inputString[i] == 'i'
|| inputString[i] == 'o'
|| inputString[i] == 'u' ) {
++noOfVowels;
}
++i;
}
std::cout << "number of vowels : " << noOfVowels << std::endl;
Well you can try this approach. This will solve your needs I guess.
#include <iostream>
#include <string>
#include <sstream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int number=0;
int zeros=0;
int ones=0;
int twos=0;
int threes=0;
int fours=0;
bool valid=true;;
int counter = 0;
cout<<"Enter the number: ";
cin >> number;
stringstream out;
out << number; //int to string
string numberString = out.str();
cout<<"\n\nNumber after string conversion : "<<numberString;
cout<<"\nPrinting this just to show that the conversion was successful\n\n\n";
while (counter < numberString.length())
{
if (numberString[counter] == '0')
zeros++;
else if(numberString[counter] == '1')
ones++;
else if(numberString[counter] == '2')
twos++;
else if(numberString[counter] == '3')
threes++;
else if(numberString[counter] == '4')
fours++;
else
valid=false;
counter++;
}
if(valid==true)
{
cout<<"\nZeros : "<<zeros;
cout<<"\nOnes : "<<ones;
cout<<"\nTwos : "<<twos;
cout<<"\nThrees : "<<threes;
cout<<"\nFours : "<<fours;
}
else
cout<<"\n\nInvalid data...base of 5 rule violated";
_getch();
return 0;
}
If you don't want to use std::string then use characters, first loop over the input from the user until ENTER is pressed.
char ch = 0;
while ((ch = cin.get()) != '\n')
{
...
}
For each character read, check if it is a digit (std::isdigit) and if it is in the range 0..4, if not quit and give some message of not being base 5
have an array of ints to keep track of the frequency of the digits
int freq[5] = {0,0,0,0,0};
after you have checked that the character is valid subtract the ascii value from the digit and use that as index in the array, increment that:
freq[ch - '0']++;
e.g.
char ch;
int freq[5] = {0};
while ((ch = cin.get()) != '\n')
{
cout << ch;
freq[ch-'0']++;
}
for (int i = 0; i < sizeof(freq)/sizeof(freq[0]); ++i)
{
cout << static_cast<char>(48+i) << ":" << freq[i] << endl;
}
Here's a useful function that counts digits:
// D returns the number of times 'd' appears as a digit of n.
// May not work for n = INT_MIN.
int D(int n, int d) {
// Special case if we're counting zeros of 0.
if (n == 0 && d == 0) return 1;
if (n < 0) n = -n;
int r = 0;
while (n) {
if (n % 10 == d) r++;
n /= 10;
}
return r;
}
In your code you can use this naively to solve the problem without any further loops.
if (D(n, 5) + D(n, 6) + D(n, 7) + D(n, 8) + D(n, 9) != 0) {
cout << "the number doesn't consist only of the digits 0..4."
}
cout << "0s: " << D(n, 0) << "\n";
cout << "1s: " << D(n, 1) << "\n";
cout << "2s: " << D(n, 2) << "\n";
cout << "3s: " << D(n, 3) << "\n";
cout << "4s: " << D(n, 4) << "\n";
You could also (or should also) use loops here to reduce the redundancy.
I present to you all a program I'm working on for my college programming course. I still have a little ways to go before it completely meets my assignment's requirements, but I've gotten a basic draft of the program error-free (supposedly) and it appears to run… but then it suddenly kicks me into Xcode's debugger and gives me:
Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)
Here's the command line output, up until it kicks me out:
-----------------------
Quarterly_sales_taxator
-----------------------
How many company divisions will we be dealing with? 2
Am I correct in assuming that there are 4 sales quarters? yes
Please enter the sales Company Division #1 brought in for Sales Quarter #1 20
(lldb)
Here's my code:
//
// quarterly_sales_taxator.cpp
// Ch. 7 program #7
//
// Created by John Doe on 11/27/12.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
void read_company_divisions_and_sales_quarters(double **, int, int);
//void write_company_divisions_and_sales_quarters_to_array(double **, int, int); // This will be used later on to read data from a file.
void display_quarterly_sales_array(double **, int, int);
string temp; // A global temporary placeholder variable; I use this several times.
int main()
{
int COMPANY_DIVISIONS,
SALES_QUARTERS = 4;
double **quarterly_sales_form;
cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";
cout << "\nHow many company divisions will we be dealing with? ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
{
cout << "\n\n------"
<< "\nError:"
<< "\n------"
<< "\n\nYou have entered an invalid choice."
<< "\nPlease type a number greater than zero. ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
}
cout << "\n\nAm I correct in assuming that there are 4 sales quarters? ";
getline(cin, temp);
// Convert to uppercase.
for (int count = 0; count < temp.length(); count ++)
{
temp[count] = toupper(temp[count]);
}
if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
{
cout << "\nOk, then how many sales quarters are we dealing with? ";
getline(cin, temp);
stringstream(temp)>>SALES_QUARTERS;
}
cout << endl << endl;
// This sets up the 2d array.
quarterly_sales_form = new double *[COMPANY_DIVISIONS];
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS); // I'll add this feature later.
cout << "\n\nHere's what you entered:\n\n";
display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// Since we used a series of pointers, we need to free the allocated space back up.
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ delete[] quarterly_sales_form[COMPANY_DIVISIONS]; }
delete[] quarterly_sales_form;
return 0;
}
/*############################################
# read_company_divisions_and_sales_quarters #
############################################*/
void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < QUARTERS; count++)
{
for (int index = 0; index < DIVISIONS; index++)
{
cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << " ";
getline(cin, temp);
stringstream(temp) >> array[count][index];
}
}
}
/*################################
# display_quarterly_sales_array #
#################################*/
void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < DIVISIONS; count++)
{
cout << "\nCompany division #" << count+1 << ":\n";
for (int index = 0; index < QUARTERS; index++)
{ cout << array[count][index] << ", "; }
}
}
Can some kind soul please tell me what I'm doing wrong?
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
In this line, COMPANY_DIVISIONS should be count.
In addition to what Dan Hulme said, it seems this line
stringstream(temp) >> array[count][index];
should really be
std::istringstream(temp) >> std::skipws >> array[index][count];
In addition to using std::istringstream rather than std::stringstream and making sure that an lvalue is at hand, which isn't strictly needed until the type read becomes more interesting, this also reverses the indices: index runs over COMPANY_DIVISIONS and count over SALES_QUARTERS.
The real question is, of course: Who hands out assignments like this? Pointer manipulations and allocations are best left to low-level library writers. This is C++ not C: we can and should use abstractions. Getting this code exception safe is a major challenge and there is no point in teaching people how to write broken (e.g. exception unsafe) code.