Is there a cleaner way to write this objective-c code?
I'm new to objective-c and programming in general. I'm a paramedic and I've decided to learn to program in objective. I've got some experience with c, which is why this program is coded this way. I was wondering if there were a more efficient way to code this with objective-c? Thank you. (The program compiles without errors, so if there's a syntax error somewhere in there it's probably because i'm new to escaping characters on boards within the code blocks)
#import <Foundation/Foundation.h>
void calcDiagnosis (float pHInput, int paCO2Input, int hCO3Input);
int main (int argc, const char * argv[]){
int i;
int repeat;
i = 0;
for(i = 0; i < 3; i++){
//Initialize lab value variables
float pH;
int paCO2;
int hCO3;
//Introduction
NSLog(@"Welcome to the ABG Lab Value Interpreter v1.0\n");
NSLog(@"Please enter the necessary values.\n");
//Gather the necessary values
NSLog(@"Enter the pH value:");
scanf("%f", &pH);
NSLog(@"Enter the PaCO2 value:");
scanf("%i", &paCO2);
NSLog(@"Enter the HCO3 value:");
scanf("%i", &hCO3);
calcDiagnosis (pH, paCO2, hCO3);
//Control Loop
NSLog(@"Again?\n 1: Yes\n 2: No");
scanf("%i", &repeat);
switch (repeat){
case 1:
i = 0;
break;
case 2:
i = 3;
break;
}
}
return 0;
}
void calcDiagnosis (float pHInput, int paCO2Input, int hCO3Input)
{
//Transfer the arguments to new variables
float pH = pHInput;
int paCO2 = paCO2Input;
int hCO3 = hCO3Input;
//////////////////////////////////
//Diagnose Respiratory Acidosis//
////////////////////////////////
//Acute
if ((pH < 7.35) && (paCO2 > 45) && (hCO3 >=22 && hCO3 <=26)) {
NSLog(@"Acute Respiratory Acidosis");
}
//Partially Compensated
if ((pH < 7.35) && (paCO2 > 45) && (hCO3 >26)) {
NSLog(@"Partially Compensated Respiratory Acidosis");
}
//Compensated
if ((pH >= 7.35 && pH <= 7.45) && (paCO2 > 45) && (hCO3 >26)) {
NSLog(@"Compensated Respiratory Acidosis");
}
///////////////////////////////////
//Diagnose Respiratory Alkalosis//
/////////////////////////////////
//Acute
if ((pH > 7.45) && (paCO2 < 35) && (hCO3 >=22 && hCO3 <=26)) {
NSLog(@"Acute Respiratory Alkalosis");
}
//Partially Compensated
if ((pH > 7.45) && (paCO开发者_如何学Python2 < 35) && (hCO3 <22)) {
NSLog(@"Partially Compensated Respiratory Alkalosis");
}
//Compensated
if ((pH >= 7.35 && pH <= 7.45) && (paCO2 < 35) && (hCO3 <22)) {
NSLog(@"Compensated Respiratory Alkalosis");
}
//////////////////////////////////
//Diagnose Metabolic Acidosis////
////////////////////////////////
//Acute
if ((pH < 7.35) && (paCO2 >= 35 && paCO2 <= 45) && (hCO3 <22)) {
NSLog(@"Acute Metabolic Acidosis");
}
//Partially Compensated
if ((pH < 7.35) && (paCO2 < 35) && (hCO3 >22)) {
NSLog(@"Partially Compensated Metabolic Acidosis");
}
//Compensated
if ((pH >= 7.35 && pH <= 7.45) && (paCO2 < 35) && (hCO3 <22)) {
NSLog(@"Compensated Metabolic Acidosis");
}
//////////////////////////////////
//Diagnose Metabolic Alkalosis///
////////////////////////////////
//Acute
if ((pH > 7.45) && (paCO2 >= 35 && paCO2 <= 45) && (hCO3 >26)) {
NSLog(@"Acute Metabolic Alkalosis");
}
//Partially Compensated
if ((pH > 7.45) && (paCO2 > 45) && (hCO3 >26)) {
NSLog(@"Partially Compensated Metabolic Alkalosis");
}
//Compensated
if ((pH >= 7.35 && pH <= 7.45) && (paCO2 > 45) && (hCO3 >26)) {
NSLog(@"Compensated Metabolic Alkalosis");
}
//////////////////////
//Diagnosis Normal///
////////////////////
if ((pH >= 7.35 && pH <= 7.45) && (paCO2 >= 35 && paCO2 <= 45) && (hCO3 >= 22 && hCO3 <= 26)) {
NSLog(@"Normal Values");
}
return;
}
This can be a difficult question. As you get more experienced you will become more comfortable with more advanced concepts. The problem you are working on is actually quite sophisticated and makes for a great training tool.
Your biggest issue is that your current solution does not use any object orientation, which can make it more difficult to maintain and/or expand in the future.
Ultimately, the question of the optimal code structure can have many answers and you may not know which is better until farther down the line until you have added more functionality to your program.
I have re-rendered your program, in what I feel is a solid end game structure (as opposed to shooting for a more meek intermediate step). Unfortunately, this may be a bit of a leap when just starting out.
There are two advanced concepts in this solution, object oriented programming and selectors. Selectors are an incredibly powerful tool that allow you to pass actual instructions around your program using variables. In your case, you can store the if statements in your Diagnosis Objects.
At any rate, please feel free to ask any questions about the following:
Vitals.h
#import <Foundation/Foundation.h>
@interface Vitals : NSObject {
float _pH;
int _paCO2;
int _hCO3;
}
- (id) initWithPH:(float)pH paCO2:(int)paCO2 hCO3:(int)hCO3;
- (float) pH;
- (int) paCO2;
- (int) hCO3;
@end
Vitals.m
#import "Vitals.h"
@implementation Vitals
- (id) initWithPH:(float)pH paCO2:(int)paCO2 hCO3:(int)hCO3 {
if (self = [super init]) {
_pH = pH;
_paCO2 = paCO2;
_hCO3 = hCO3;
}
return self;
}
- (float) pH {return _pH;}
- (int) paCO2 {return _paCO2;}
- (int) hCO3 {return _hCO3;}
@end
Diagnosis.h
#import <Foundation/Foundation.h>
@class Vitals;
@interface Diagnosis : NSObject {
NSString* _name;
id _delegate;
SEL _test;
}
- (id) initWithName:(NSString*)name delegate:(id)delegate test:(SEL)test;
- (NSString*) name;
- (BOOL) test:(Vitals*)vitals;
@end
Diagnosis.m
#import "Diagnosis.h"
@implementation Diagnosis
- (id) initWithName:(NSString*)name delegate:(id)delegate test:(SEL)test {
if (self = [super init]) {
_name = [name retain];
_delegate = delegate;
_test = test;
}
return self;
}
- (void) dealloc {
[_name release];
[super dealloc];
}
- (NSString*) name {return _name;}
- (BOOL) test:(Vitals*)vitals {
return [(NSNumber*)[_delegate performSelector:_test withObject:vitals] boolValue];
}
@end
Doctor.h
#import <Foundation/Foundation.h>
@class Vitals;
@class Diagnosis;
@interface Doctor : NSObject {
NSMutableArray* _diagnoses;
}
- (void) learnDiagnosis:(Diagnosis*)diagnosis;
- (Diagnosis*) diagnose:(Vitals*)vitals;
@end
Doctor.m
#import "Diagnosis.h"
#import "Doctor.h"
@implementation Doctor
- (id) init {
if (self = [super init]) {
_diagnoses = [[NSMutableArray alloc] init];
}
return self;
}
- (void) dealloc {
[_diagnoses release];
[super dealloc];
}
- (void) learnDiagnosis:(Diagnosis*)diagnosis {
[_diagnoses addObject:diagnosis];
}
- (Diagnosis*) diagnose:(Vitals*)vitals {
for (Diagnosis* diagnosis in _diagnoses) {
if ([diagnosis test:vitals])
return diagnosis;
}
return 0;
}
@end
Differential.h
#import <Foundation/Foundation.h>
@interface Differential : NSObject {}
- (void) teach:(Doctor*)doctor;
@end
Differential.m
#import "Vitals.h"
#import "Diagnosis.h"
#import "Doctor.h"
#import "Differential.h"
@implementation Differential
- (NSNumber*) acuteRespiratoryAcidosis:(Vitals*)vitals {
return [NSNumber numberWithBool:(([vitals pH] < 7.35) && ([vitals paCO2] > 45) && ([vitals hCO3] >=22 && [vitals hCO3] <=26))];
}
- (NSNumber*) partiallyCompensatedResporatoryAcidosis:(Vitals*)vitals {
return [NSNumber numberWithBool:(([vitals pH] < 7.35) && ([vitals paCO2] > 45) && ([vitals hCO3] >26))];
}
- (void) teach:(Doctor*)doctor {
Diagnosis* diagnosis;
diagnosis = [[Diagnosis alloc] initWithName:@"Acute Respiratory Acidosis" delegate:self test:@selector(acuteRespiratoryAcidosis:)];
[doctor learnDiagnosis:diagnosis];
[diagnosis release];
diagnosis = [[Diagnosis alloc] initWithName:@"Partially Compensated Respiratory Acidosis" delegate:self test:@selector(partiallyCompensatedResporatoryAcidosis:)];
[doctor learnDiagnosis:diagnosis];
[diagnosis release];
}
@end
Sandbox.h
#import <Foundation/Foundation.h>
#import "Vitals.h"
#import "Diagnosis.h"
#import "Doctor.h"
#import "Differential.h"
void run () {
float pH=7.2;
int paCO2=47;
int hCO3=25;
Doctor* doctor = [[Doctor alloc] init];
Differential* differential = [[Differential alloc] init];
[differential teach:doctor];
Vitals* vitals = [[Vitals alloc] initWithPH:pH paCO2:paCO2 hCO3:hCO3];
Diagnosis* diagnosis = [doctor diagnose:vitals];
NSLog(@"%@",[diagnosis name]);
[vitals release];
[differential release];
[doctor release];
}
While there are a couple of problems with the code you've posted, the biggest issue is using a for
loop where it would be more natural to use a while
loop. for
is generally for iterating (reading or writing to each element in an array, for instance). while
is for generally for repeating a task multiple (but in indefinite) amount of times. There are a couple of different ways you could accomplish this, but a simple modification would be as follows:
int main (int argc, const char * argv[]){
int menu_input = 0;
while(menu_input != 2){
//Initialize lab value variables
float pH;
int paCO2;
int hCO3;
//Introduction
NSLog(@"Welcome to the ABG Lab Value Interpreter v1.0\n");
NSLog(@"Please enter the necessary values.\n");
//Gather the necessary values
NSLog(@"Enter the pH value:");
scanf("%f", &pH);
NSLog(@"Enter the PaCO2 value:");
scanf("%i", &paCO2);
NSLog(@"Enter the HCO3 value:");
scanf("%i", &hCO3);
calcDiagnosis (pH, paCO2, hCO3);
//Control Loop
NSLog(@"Again?\n 1: Yes\n 2: No");
scanf("%i", &menu_input);
}
return 0;
}
As mentioned in your post, though, it would serve you well to do some basic input checking if this is being used in a real world environment.
Are you learning Objective-C to write Mac or iPhone programs? I will assume so because that is arguably the main reason people learn it. If you haven't already, you should look at Apple Developer website where they have a lot of helpful tutorials, etc. I think you should try making this into a GUI application because you will be using more Objective-C and Cocoa that way. You have really written a C program except for the NSLog()'s (and the NSStrings inside them). Here is a nice tutorial.
精彩评论