My attempt. Didn't want to use Try, Except though I think it might of been easier if I did. Didn't test it as thoroughly as I probably should of either but I think I covered all bases.
PHP Code:
#!/usr/bin/env python
import sys
def name(input):
if not input or input[0] == ' ':
return False
return True
def num(input, info):
if input.isdigit():
if input[0] not in ('0', '-'):
if info == 'age' and int(input) > 130:
return False
return True
def input_data(info):
options = {'age': '\nPlease enter your age: ',
'name': '\nPlease enter your forum name: ',
'fuid': '\nPlease enter your forum user ID: '}
result = ''
while not result:
result = raw_input(options[info])
if result.lower() == 'quit':
print '\nExiting Program, Goodbye'
sys.exit()
if (info == 'age' or info == 'fuid') and num(result, info):
return result
if info == 'name' and name(result):
return result
result = ''
print 'Invalid entry, please try again'
print "Welcome to the info gatherer. \
Type 'quit' at any prompt to exit the program"
name = input_data('name').strip()
age = input_data('age').strip()
fuid = input_data('fuid').strip()
print '\nYou are %s, aged %s, next year you will be %s, with user id \
%s the next user is %s' % (name, age, int(age)+1, fuid, int(fuid)+1)
Here is my code... after much procrastination (read: several months) I am starting to take Python seriously... I have been told that this code is not very Pythonic... but I do believe it works properly.
tools used - IDLECode:#!/usr/bin/env python # challeng2.py # A program to handle text and numeric input # by PrivateVoid import sys sError = "there was an error in your entry please re-enter" sBlank = "your entry was blank please re-enter" def test(n): if n > 0 and n < 1000000 and n % 1 == 0: return True else: return False def __exit__(s): if s == "exit": sys.exit(0) def blank(r): if len(r) == 0: return True else: return False def age(): aInput = raw_input("how old are you? (must be an integer between 1 and 999999) ") try: __exit__(aInput) if blank(aInput): print sBlank return age() elif not test(int(aInput)): print "your entry was not an integer between 1 and 999999 please re-enter" return age() print aInput return int(aInput) except ValueError: print sError age() def name(): aName = raw_input("please enter your name (your name can not begin with a space) ") try: __exit__(aName) bName = aName.lstrip(' ') if len(aName) > len(bName): print "your entry started with a space please re-enter" return name() elif blank(aName): print sBlank return name() return aName except ValueError: print sError name() def forumid(): aID = raw_input("please enter your forum ID (must be an integer between 1 and 999999) ") try: __exit__(aID) if not test(int(aID)): print "your entry was not an integer between 1 and 999999 please re-enter" return forumid() elif blank(aID): print sBlank return forumid() return int(aID) except ValueError: print sError forumid() def main(): print "To leave the program please just type 'exit' at any prompt" sName = name() sAge = age() sID = forumid() print "You are ", sName, " aged ", sAge, "next year you will be ", sAge+1, ", with user id ", sID, "the next user is ", sID+1, "." main()
can not wait for a critique and to see the other entries.
Okay, here's my C version. Though it might seem a bit overkill, I used a separate header file for the sake of good practice.
challenge2.h
challenge2.cPHP Code:
#ifndef CHALLENGE_2
#define CHALLENGE_2
#define MAX_AGE 130
#define MAX_UID 9999999
#define MAX_USERNAME_LENGTH 20
void initUser (void);
void promptName (void);
void promptAge (void);
void promptUid (void);
void printString (void);
void destroyUser (void);
#endif
Place in the same directory and compile withPHP Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "challenge2.h"
/* The macros below are a little preprocessor trick to allow usage of other macro
* values as string constants.
* For more information, see: http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
*/
#define xstr(s) str(s)
#define str(s) #s
static char* name;
static int age;
static int uid;
void initUser(void)
{
//First, we initialize the variables
name = (char*) calloc(MAX_USERNAME_LENGTH + 1, sizeof(char));
age = 0;
uid = 0;
//Nice greeting message...
printf("Okay, I'm going to ask you a few details about yourself.\n");
printf("Remember that at any prompt, you may type \"exit\" to quit.\n\n");
//And we prompt for the values
promptName();
promptAge();
promptUid();
}
void testInputForExit(char* input)
{
if(!strcmp(input, "exit"))
{
printf("Good bye!\n");
exit(0);
}
}
void cleanBuffer(void)
{
/* This is used to clean the buffer after every input, in order to avoid
* potential buffer overflow issues, as well not to pollute further inputs.
*/
int c;
while(((c = getchar()) != '\n') && c != EOF)
{;}
}
int toInt(char* input, int max_value)
{
/* This function is used to check whether or not the string given as input
* is "convertible" to an integer. Unlike atoi() and friends, this requires
* _all_ the characters in the string to be digits. Since the minus sign is
* not allowed, only positive integers are. Additionally, this function also
* checks whether the converted integer is smaller than max_value.
*
* This functions returns the converted positive integer on success.
* On failure, it returns -1 if the input was not a positive integer, and
* -2 if it exceeded the limit.
*/
unsigned i = 0;
while(i < strlen(input))
{
if(!isdigit(input[i]))
return -1;
i++;
}
return (atoi(input) > max_value) ? -2 : atoi(input);
}
char* prompt(unsigned maxStringLength)
{
char* buffer = calloc(maxStringLength + 1, sizeof(char));
unsigned i;
/* This is where the xstr macro comes into play. It allows us to always have
* a maximum input length sufficient to contain all the values, but no more
* (for the sake of simplicity, we assume that MAX_USERNAME_LENGTH will always
* be the longest one. Who needs twenty-digits ages anyway?).
*/
scanf(" %" xstr(MAX_USERNAME_LENGTH) "[^\n]", buffer);
cleanBuffer();
//Remove trailing spaces (if any)
for(i = strlen(buffer) - 1; i >= 0; i--)
{
if(isspace(buffer[i]))
buffer[i] = '\0';
else if(isgraph(buffer[i]))
break;
}
testInputForExit(buffer);
return buffer;
}
void promptName(void)
{
printf("Please enter your username and press Enter.\n");
char* tmp = prompt(MAX_USERNAME_LENGTH);
memccpy(name, tmp, '\0', MAX_USERNAME_LENGTH);
free(tmp);
}
void promptAge(void)
{
printf("Now, please enter your age.\n");
while(1)
{
char* tmp = prompt(MAX_USERNAME_LENGTH);
if((age = toInt(tmp, MAX_AGE)) < 1)
{
if(age >= -1)
printf("Error. Please enter a strictly positive integer.\n");
else
printf("Error. Please enter an integer lower than %u.\n", MAX_AGE);
}
else
break;
}
free(tmp);
}
void promptUid(void)
{
printf("Almost there! Now, please enter your user ID.\n");
while(1)
{
char* tmp = prompt(MAX_USERNAME_LENGTH);
if((uid = toInt(tmp, MAX_UID)) < 1)
{
if(uid >= -1)
printf("Error. Please enter a strictly positive integer.\n");
else
printf("Error. Please enter an integer lower than %u.\n", MAX_UID);
}
else
break;
}
free(tmp);
}
void printString(void)
{
printf("You are %s, aged %d next year you will be %d, with user id %u the next user is %u.\n",
name, age, age+1, uid, uid+1);
}
void destroyUser(void)
{
printf("Good bye, %s!\n", name);
free(name);
}
int main(void)
{
initUser();
printString();
destroyUser();
return 0;
}
Code:cc -o challenge2 challenge2.c
Last edited by Bachstelze; August 8th, 2008 at 10:17 PM.
My first attempt at using (common? maybe?) lisp. I tried it with scbl and clisp interpreters, and it worked. By the way it messed up with php tags, so I used code.
Code:(defun check-name-nil (name) (if (STRING-EQUAL name "") t nil)) (defun check-name-start-space (name) (if (STRING-EQUAL (subseq name 0 1) " ") t nil)) (defun check-name-not-contains-char (name) (loop for c across name do (if (alpha-char-p c) (return-from check-name-not-contains-char nil) ())) t) (defun get-name () (loop do (format t "Whats be yo tag yo: ") (finish-output) (let ((name (read-line t))) (if (STRING-EQUAL name "exit") (quit) (if (check-name-nil name) (format t "Yuz ain't nosbody~%") (if (check-name-start-space name) (format t "Yuz tag gotta start wit a character yo~%") (if (check-name-not-contains-char name) (format t "Yo i didn' ask fo yuz digits~%") (return-from get-name name)))))))) (defun get-age () (loop do (format t "How old bez yo: ") (finish-output) (let ((age (read))) (if (typep age 'REAL) (if (<= age 0) (format t "Howz yuz typin' from da womb?~%") (if (>= age 120) (format t "Howz yuz not dead?~%") (return-from get-age age))) (if (STRING-EQUAL age "exit") (quit) (format t "Yuz age needzta be a numba~%")))))) (defun get-id () (loop do (format t "Whats yuz forum numba: ") (finish-output) (let ((id (read))) (if (typep id 'REAL) (if (<= id 0) (format t "No onez got dis forum numba~%") (if (> id 999999) (format t "No onez got dis forum numba~%") (return-from get-id id))) (if (STRING-EQUAL id "exit") (quit) (format t "Yuz forum numba needzta be a numba~%")))))) (defun main () (format t "Follow da prompts or enta exit anywhere to exit~2%") (let ((name (get-name)) (age (get-age)) (id (get-id))) (format t "You are ~A, aged ~A next year you will be ~A, with user id ~A, the next user is ~A." name age (+ age 1) id (+ id 1)))) (main)
Last edited by PandaGoat; August 8th, 2008 at 10:38 AM.
C++ again. I tried to abstract the validation of things as much as possible. This was good practice for using templates too.
PHP Code:
#include <vector>
#include <string>
#include <iterator>
#include <iostream>
#include <sstream>
class ValidatorPolicy
{
public:
ValidatorPolicy() { }
virtual ~ValidatorPolicy() { }
virtual bool validate(int value) const = 0;
virtual bool validate(const std::string& value) const = 0;
};
class FullPolicy : public ValidatorPolicy
{
public:
FullPolicy() { }
virtual ~FullPolicy() { }
virtual bool validate(int value) const { return true; }
virtual bool validate(const std::string& value) const { return true; }
};
class RangePolicy : public FullPolicy
{
public:
RangePolicy(int min, int max)
{
m_min = min;
m_max = max;
}
~RangePolicy() { }
bool validate(int value) const
{
if (value > m_min && value < m_max)
{
return true;
}
return false;
}
private:
int m_min;
int m_max;
};
class NamePolicy : public FullPolicy
{
public:
NamePolicy() { }
~NamePolicy() { }
bool validate(const std::string& value) const
{
if (value[0] == ' ' || value.empty())
return false;
return true;
}
};
template <typename T> class Validator
{
public:
Validator() { }
~Validator()
{
while (!m_policies.empty())
{
delete m_policies.back();
m_policies.pop_back();
}
}
void addPolicy(ValidatorPolicy* policy)
{
m_policies.push_back(policy);
}
bool validateAll(const T& value)
{
std::vector<ValidatorPolicy*>::iterator i;
for (i = m_policies.begin(); i != m_policies.end(); ++i)
{
if (!isValid((*i), value))
return false;
}
return true;
}
bool isValid(ValidatorPolicy* policy, const T& value)
{
return policy->validate(value);
}
private:
std::vector<ValidatorPolicy*> m_policies;
};
class Application
{
public:
Application() { }
virtual ~Application() { }
virtual int exec() = 0;
};
class ValidatorApplication : public Application
{
public:
ValidatorApplication()
{
m_nameValidator.addPolicy(new NamePolicy());
m_ageValidator.addPolicy(new RangePolicy(5, 120));
m_forumIdValidator.addPolicy(new RangePolicy(0, 99999));
}
~ValidatorApplication() { }
int exec()
{
std::cout << "Type your info or \"exit\" to exit."
<< std::endl << std::endl;
std::string s;
do
{
if (!input("Please input your name: ", s))
{
return 0;
}
else
{
m_name = s;
}
}
while (!m_nameValidator.validateAll(m_name));
do
{
if (!input("Plese input your age: ", s))
{
return 0;
}
else
{
std::istringstream stream(s);
stream >> m_age;
}
}
while (!m_ageValidator.validateAll(m_age));
do
{
if (!input("Please input your forum id: ", s))
{
return 0;
}
else
{
std::istringstream stream(s);
stream >> m_forumId;
}
}
while (!m_forumIdValidator.validateAll(m_forumId));
std::cout << "You're " << m_name << " aged " << m_age << " next ";
std::cout << "near you'll be " << m_age + 1 << ", with user id ";
std::cout << m_forumId << ", the next user is " << m_forumId + 1;
std::cout << std::endl;
return 0;
}
private:
bool input(const std::string& prompt, std::string& command)
{
std::cout << prompt;
getline(std::cin, command);
if (command == "exit")
return false;
return true;
}
std::string m_name;
int m_age;
int m_forumId;
Validator<std::string> m_nameValidator;
Validator<int> m_ageValidator;
Validator<int> m_forumIdValidator;
};
int main(int argc, char* argv[])
{
ValidatorApplication app;
return app.exec();
}
Now that I'm done I'll look at the other entries.
Code:#!/usr/bin/env python runiftrue = 1 while runiftrue: while 1: try: namein = raw_input('Enter your name, press "Enter" when complete. ') if len(namein) == 0: print 'Not enough characters.' continue if namein[0] == ' ': print "Don't start name with a space." continue if namein == "quit": print 'Goodbye' runiftrue = 0 break if len(namein) > 20: namein = namein[0:19] print 'name truncated' break except: print 'Input error, try again.' continue if runiftrue == 0: break while 1: try: agein = raw_input('Enter your age, press "Enter" when complete. ') if len(agein) == 0: print 'Not enough characters.' continue if agein == "quit": print 'Goodbye' runiftrue = 0 break if not agein.isdigit(): print 'Enter a number for your age.' continue if int(agein) < 1: print 'Too low, try again.' continue break except: print 'Input error, try again.' continue if runiftrue == 0: break while 1: try: useridin = raw_input('Enter your Forum User ID, press "Enter" when complete. ') if useridin == "quit": print 'Goodbye' runiftrue = 0 break if len(useridin) == 0: print 'Not enough numbers.' continue if not useridin.isdigit(): print 'Enter the number of your Forum User ID.' continue if int(useridin) > 999999: print 'Too high, try again.' continue if int(useridin) < 1: print 'Too low, try again.' continue if len(useridin) > 20: useridin = useridin[0:19] print 'name truncated' break except: print 'Input error, try again.' continue if runiftrue == 0: break print '''You are %s, age %i, next year you will be %i, with user id %i, the next user is %i.''' % (namein, int(agein), int(agein)+1, int(useridin), int(useridin) + 1) break
Bookmarks