3
\$\begingroup\$

I'm making a converter app, and after realising I would have to type about 200 lines of code to get it working with more than 5 units converted, I should have a better conversion calculation.

What I have currently is a ifelse that find out what units i selected from the wheel, a sting to find out what it should answer and a float to calculate. It looks like this atm:

 #import "MainViewController.h"
 @interface MainViewController ()

 @end

  @implementation MainViewController;

 @synthesize _convertFrom, _convertTo, _convertRates;
@synthesize inputText, picker, resultLabel;
- (void)viewDidLoad
{
  [super viewDidLoad];
  {
    [super viewDidLoad];

    _convertFrom = @[@"MTPA", @"MMcf/day",
    @"Mill.Sm3/day", @"MMBTU", @"Boe/day"];

    _convertRates = @[ @1.0f, @2.0f, @3.0f,
    @4.0f, @5.0f];

    _convertTo = @[@"MTPA", @"MMcf/day",
    @"Mill.Sm3/day", @"MMBTU", @"Boe/day"];

_convertRates = @[ @1.0f, @2.0f, @3.0f,
@4.0f, @5.0f];
} 
}
 - (void)didReceiveMemoryWarning
  {
   [super didReceiveMemoryWarning];

 }


  -(IBAction)textFieldReturn:(id)sender
  {
    [sender resignFirstResponder];
 }
-(IBAction)backgroundTouched:(id)sender
 {
[inputText resignFirstResponder];
}


 #pragma mark -
 #pragma mark PickerView DataSource

 - (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
 return 2;
 }

 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:            (NSInteger)component
 {
if (component == 0)  {
    return [_convertFrom count];
}
return [_convertTo count];
 }


- (NSString *) pickerView: (UIPickerView *)pickerView
      titleForRow:(NSInteger)row
     forComponent:(NSInteger)component
{
if (component == 0) {
    return [_convertFrom objectAtIndex:row];
}
return [_convertTo objectAtIndex:row];
}




 #pragma mark -
 #pragma mark PickerView Delegate
 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
 {
float convertFrom = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0]]       floatValue];
 float convertTo = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1]]    floatValue];
 float input = [inputText.text floatValue];
 float to = convertTo;
 float from = convertFrom;
  float convertValue = input;

 float MTPATilMTPAFloat               = convertValue * 1;
 float MTPATilMMScfdayFloat           = convertValue * 133.425;
  float MTPATilMillSm3dayFloat         = convertValue * 3.779735;
  float MTPATilMMBTUFloat              = convertValue * 4;
 float MTPATilboedayFloat               = convertValue * 5;

 float MMScfdayTilMTPAFloat           = convertValue * 0.5;
 float MMScfdayTilMMScfdayFloat       = convertValue * 1;
 float MMScfdayTilMillSm3dayFloat     = convertValue * 6;
 float MMScfdayTilMMBTUFloat          = convertValue * 7;
 float MMScfdayTilboedayFloat           = convertValue * 8;

  float MillSm3dayTilMTPAFloat = convertValue / 1;
 float MillSm3dayTilMMScfdayFloat = convertValue / 2;
 float MillSm3dayTilMillSm3dayFloat = convertValue / 3;
 float MillSm3dayTilMMBTUFloat = convertValue / 4;
 float MillSm3dayTilboedayFloat = convertValue / 5;

 float MMBTUTilMTPAFloat = convertValue * 2;
 float MMBTUTilMMScfdayFloat = convertValue * 2;
 float MMBTUTilMillSm3dayFloat = convertValue * 2;
 float MMBTUTilMMBTUFloat = convertValue * 2;
 float MMBTUTilboeday = convertValue * 2;

float boedayTilMTPAFloat = convertValue * 3;
float boedayTilMMScfdayFloat = convertValue * 3;
float boedayTilMillSm3dayFloat = convertValue * 3;
float boedayTilMMBTUFloat = convertValue * 3;
float boedayTilboeday = convertValue * 3;





NSString *MTPATilMTPA = [[NSString alloc ] initWithFormat:
                     @" %f MTPA = %f MTPA", convertValue, MTPATilMTPAFloat];

NSString *MTPATilMMScfday = [[NSString alloc ] initWithFormat:
                         @" %f MTPA = %f MMScf/day", convertValue, MTPATilMMScfdayFloat];

NSString *MTPATilMillSm3day = [[NSString alloc] initWithFormat:
                           @" %f MTPA = %f Mill.SM3/day", convertValue,          MTPATilMillSm3dayFloat];

NSString *MTPATilMMBTU = [[NSString alloc] initWithFormat:
                      @" %f MTPA = %f MMBTU", convertValue, MTPATilMMBTUFloat];

NSString *MTPATilboeday = [[NSString alloc] initWithFormat:
                     @" %f MTPA = %f Boe/day", convertValue, MTPATilboedayFloat];




NSString *MMScfdayTilMTPA = [[NSString alloc] initWithFormat:
                         @" %f MMScfday = %f MTPA", convertValue, MMScfdayTilMTPAFloat];

NSString *MMScfdayTilMMScfday = [[NSString alloc] initWithFormat:
                             @" %f MMScfday = %f MMScfday", convertValue,       MMScfdayTilMMScfdayFloat];

NSString *MMScfdayTilMillSm3day = [[NSString alloc] initWithFormat:
                               @" %f MMScfday = %f MillSm3day", convertValue,        MMScfdayTilMillSm3dayFloat];

NSString *MMScfdayTilMMBTU = [[NSString alloc] initWithFormat:
                          @" %f MMScfday = %f MMBTU", convertValue,        MMScfdayTilMMBTUFloat];

 NSString *MMScfdayTilboeday = [[NSString alloc] initWithFormat:
                         @" %f MMScfday = %f Boe/day", convertValue, MMScfdayTilboedayFloat];




NSString *MillSm3dayTilMTPA = [[NSString alloc] initWithFormat:
                           @" %f MillSm3day = %f MTPA", convertValue, MillSm3dayTilMTPAFloat];



if (from == 1) {
  if (to == 1) {
    resultLabel.text = MTPATilMTPA;
}
else if (to == 2) {
    resultLabel.text = MTPATilMMScfday;
}
else if (to == 3) {
    resultLabel.text = MTPATilMillSm3day;
}
else if (to == 4) {
    resultLabel.text = MTPATilMMBTU;
}
else if (to == 5) {
    resultLabel.text = MTPATilboeday;
}
}
else if (from == 2) {
  if (to == 1) {
     resultLabel.text = MMScfdayTilMTPA;
 }
 else if (to == 2) {
    resultLabel.text = MMScfdayTilMMScfday;
 }
 else if (to == 3) {
     resultLabel.text = MMScfdayTilMillSm3day;
 }
 else if (to == 4) {
     resultLabel.text = MMScfdayTilMMBTU;
 }
 else if (to == 5) { 
     resultLabel.text = MMScfdayTilboeday;
  }
}
}

As you can see, a huge mess with alot of more code needed if I want more units.

When I realised that, i tried to calculate it by using a commmon variable that I convert everything into, and then convert back into a output unit. Think of it with lenght calculation. The common variable i want everything to be converted to first, is meters. so 1 meters = 1, 1 cm = 0.01 and 1 mm = 0.001. So, if I wanted to calculate, i would use.

unitIwantToConvertToComparedTo1Meter = 0.5 (of 1 meter) result = from * to * input * unitIwantToConvertToComparedTo1Meter.

Which, surprisingly, works. As used here:

#import "MainViewController.h"
@interface MainViewController ()

@end

@implementation MainViewController;

@synthesize _convertFrom, _convertTo, _convertRates;
@synthesize inputText, picker, resultLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
{
    [super viewDidLoad];

    _convertFrom = @[@"Kubikk M", @"Kubikk CM",
    @"Kubikk MM", @"MMBTU", @"Boe/day"];

    _convertRates = @[ @1.0f, @0.01f, @0.001f,
    @4.0f, @5.0f];

_convertTo = @[@"Kubikk M", @"Kubikk CM",
@"Kubikk MM", @"MMBTU", @"Boe/day"];

_convertRates = @[ @1.0f, @0.01f, @0.001f,
@4.0f, @5.0f];
}
}
 - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}


-(IBAction)textFieldReturn:(id)sender
{
[sender resignFirstResponder];
}
 -(IBAction)backgroundTouched:(id)sender
{
[inputText resignFirstResponder];
}


#pragma mark -
#pragma mark PickerView DataSource

- (NSInteger)numberOfComponentsInPickerView:
 (UIPickerView *)pickerView
{
return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:   (NSInteger)component
{
if (component == 0)  {
return [_convertFrom count];
}
return [_convertTo count];
}


- (NSString *) pickerView: (UIPickerView *)pickerView
      titleForRow:(NSInteger)row
     forComponent:(NSInteger)component
{
if (component == 0) {
    return [_convertFrom objectAtIndex:row];
}
return [_convertTo objectAtIndex:row];
}




#pragma mark -
#pragma mark PickerView Delegate
 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
 {
 float convertFrom = [[_convertRates objectAtIndex:[pickerView     selectedRowInComponent:0]]    floatValue];
 float convertTo = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1]]    floatValue];
 float input = [inputText.text floatValue];
 float to = convertTo;
 float from = convertFrom;
 float convertValue = input;

 float kubikkfot = 0.1;

 float result = from * convertValue * kubikkfot;



 NSString *resultString = [[NSString alloc ] initWithFormat:
                     @" %f MTPA = %f MTPA", convertValue, result];
 resultLabel.text = resultString;
 }
\$\endgroup\$
3
\$\begingroup\$

Copied from SO with a few edits and additions.


Dude use C arrays to create an nxn matrix of conversions. Then just have one array with unit names in it. Done and done. If you don't know what a matrix is, then you have more theory to learn.

It goes like this. M is your conversion matrix:

M:      inch      meter
      +-----------------
inch  | 1        0.0254
meter | 39.3701  1

So if x is in inches then M[inch][meter] * x is the same length in meters.

And M[i][j] * M[j][i] == 1. Always.

You will have a different conversion matrix for each quantity that you are measuring. That is, you will have one for heat, one for time, one for distance (the example above), one for energy, one for force... etc.

Then each measure is just an index value:

enum { inch = 0, meter = 1 };
typedef unsigned int MeasureType;

And you can name them like so:

NSArray *measureNames = [NSArray arrayWithObjects:@"Inches", @"Meters", nil];

And you might want to have images for each:

UIImage *inchesImage = [UIImage imageNamed:@"inches_icon"];
UIImage *metersImage = [UIImage imageNamed:@"meters_icon"];
NSArray *measureImages = [NSArray arrayWithObjects:inchesImage, metersImage, nil];

And now you have the foundation for building up your GUI and architecture. More than this I won't answer - unless you pay me!

Good luck!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.