Problem Set 2: Caesar
Evidence of a 5-point submission
- Makes use of the
isdigit
function to check for a valid key using a method that will short-circuit (that is, end before checking every digit) if a non-digit is found - Checks for a non-negative key
- Uses a robust and efficient method for calculating the ciphertext
- Minimal code repeated, uses fewest values possible
- No extraneous variables
(letter - base + key) % ALPHASIZE + base
- Does not calculate
% ALPHASIZE
more than once
- Uses
isupper
andislower
functions - Prints the ciphertext out directly (no unnecessary variables)
- Does not include 26 as a magic number
Evidence of a 4-point submission
- Makes use of the
isdigit
function to check for a valid key using a method that will short-circuit (that is, end before checking every digit) if a non-digit is found - Checks for a non-negative key
- Uses a reasonably efficient value for calculating the ciphertext (does not compute
% ALPHASIZE
more than once) - Uses
isupper
andislower
functions - Prints the ciphertext out directly (no unnecessary variables)
Evidence of a 3-point submission
- Uses a short-circuiting method to check the key
- Calculates the shift using a reasonable and clear method (few unnecessary parentheses, few unnecessary or repeated variables, not all written on one line; may use intermediary variables to break up the length of the calculation)
Evidence of a 2-point submission
- After error-handling in an
if
statement which returns1
, wraps the rest of the code in an unnecessaryelse
statement - Checking for an entirely numeric key does not short-circuit
- Calculates the shift using a confusing and/or unnecessary method
Evidence of a 1-point submission
- After error-handling in an
if
statement which returns1
, wraps the rest of the code in an unnecessaryelse
statement - Checking for an entirely numeric key does not short-circuit
- Uses unnecessary variables and/or conditionals
- Calculates the shift using a method that is very unclear
Example Implementations (Worse vs. Better)
Error Handling
Worse Implementation
The example below includes an unnecessary else
statement.
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
else
{
// the rest of the program is written in this statement
...
}
Better Implementation
The example below error handles without unnecessary conditionals.
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
...
Validate Key
Worse Implementation
Even though the example below uses the isdigit
function, it will not short-circuit and therefore requires unnecessary computation.
int length = strlen(s);
int digitcount = 0;
for (int i = 0; i < length; i++)
{
if (isdigit(s[i]))
{
digitcount += 1;
}
}
if (digitcount == length)
{
return 1;
}
else
{
return 0;
}
Better Implementation
The example below will short circuit, and it uses the characters to represent numbers (as opposed to ASCII values).
int n = strlen(s);
for (int i = 0; i < n; i++)
{
if (s[i] > '9' || s[i] < '0')
{
return 1;
}
}
Best Implementation
The example below uses the isdigit
function. Note also the use of the !
operator.
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if (!isdigit(argv[1][i]))
{
printf("Usage: ./caesar key\n");
return 1;
}
}
Calculate Shift
Worse Implementation
Note, the example below is from a student-defined rotate
helper function. While this example does use an appropriate equation, it includes unnecessary conditionals, variables, and magic numbers.
if (isalpha(c))
{
if (c < 91)
{
c = c - 65;
char newchar = ((c + n) % 26);
return newchar + 65;
}
else
{
c = c - 97;
char newchar = ((c + n) % 26);
return newchar + 97;
}
}
else
{
return c;
}
Better Implementation
In the example below, minimal code reused, handles uppercase, lowercase, and non-alphabetical characters uniquely. This example also does not require the use of an extra variable to store the ciphertext.
for (int i = 0, n = strlen(plaintext); i < n; i++)
{
if (isupper(plaintext[i]))
{
printf("%c", ((plaintext[i] - 'A' + key) % ALPHASIZE + 'A'));
}
else if (islower(plaintext[i]))
{
printf("%c", ((plaintext[i] - 'a' + key) % ALPHASIZE + 'a'));
}
else
{
printf("%c", plaintext[i]);
}
}