How to handle weight conversions - ios

I'm currently facing an issue converting between metrics and imperial weights when working with gym equipment. So here in the UK we work with weights in Kilo's where they can increment by 1.25, but overseas i.e. US the weights are measured in pounds and can increment by 0.5.
Handling this isn't an issue, the issue arises when I use the formula to convert between kilo, pounds and vice versa the values are way off. For example a standard UK barbell is 20KG and a US barbell is 45lbs, but when i use the Measurement class to convert it will spit out 44.0925. I already know to convert kilo to pounds you have to multiply it by 2.205 but this is just one example and other values are just as way off.
I've already thought of some other possible solutions one being having an array of possible values in kilos and another that will hold a possible values in pounds but this feels hacky and also wouldn't work since users can input their values into a textfield, which may be an invalid value.
Just curious to see/know if anyone has tackled switching between weight conversion before especially with gym equipment.

I have achieved this by keeping what user has selected option is like it is pound or kg
enum WeightUnitConverted:String {
case kg = "kg"
case pounds = "pound"
case none = ""
}
var weightUnitConvertedValue: WeightUnitConverted = WeightUnitConverted.kg
You have to change this weightUnitConvertedValue whenever the user changes the measurement type. before that you can convert the values
like this I have MVVM
self.viewModel.updateWeightUnit(string: self.weightUnit[selectedRow]) // Like kg or pound, So self.viewModel.weightUnit = "kg"
self.viewModel.updateWeight(string: self.viewModel.convertWeightValues())
self.txtWeight.text = self.viewModel.weight
self.viewModel.weightUnitConvertedValue = WeightEntryViewModel.WeightUnitConverted(rawValue: self.viewModel.weightUnit)!
Here is convertWeightValues()
func convertWeightValues() -> String {
// We need to convert to pounds
if weightUnit.lowercased() == "pound" && weightUnitConvertedValue == .kg {
let punds = convertKGtoPounds()
return punds > 0 ? punds.asNumber : ""
} else if weightUnit.lowercased() == "kg" && weightUnitConvertedValue == .pounds {
// We need to convert to KG
let kg = convertPoundsToKG()
return kg > 0 ? kg.asNumber : ""
}
return self.weight //No need to change so return current weight
}
I know this is a bit confusing for you to implement someone's code Please ask me whatever query you have

Related

toStringAsFixed() returns a round-up value of a given number in Dart

I want to get one decimal place of a double in Dart. I use the toStringAsFixed() method to get it, but it returns a round-up value.
double d1 = 1.151;
double d2 = 1.150;
print('$d1 is ${d1.toStringAsFixed(1)}');
print('$d2 is ${d2.toStringAsFixed(1)}');
Console output:
1.151 is 1.2
1.15 is 1.1
How can I get it without a round-up value? Like 1.1 for 1.151 too. Thanks in advance.
Not rounding seems highly questionable to me1, but if you really want to truncate the string representation without rounding, then I'd take the string representation, find the decimal point, and create the appropriate substring.
There are a few potential pitfalls:
The value might be so large that its normal string representation is in exponential form. Note that double.toStringAsFixed just returns the exponential form anyway for such large numbers, so maybe do the same thing.
The value might be so small that its normal string representation is in exponential form. double.toStringAsFixed already handles this, so instead of using double.toString, use double.toStringAsFixed with the maximum number of fractional digits.
The value might not have a decimal point at all (e.g. NaN, +infinity, -infinity). Just return those values as they are.
extension on double {
// Like [toStringAsFixed] but truncates (toward zero) to the specified
// number of fractional digits instead of rounding.
String toStringAsTruncated(int fractionDigits) {
// Require same limits as [toStringAsFixed].
assert(fractionDigits >= 0);
assert(fractionDigits <= 20);
if (fractionDigits == 0) {
return truncateToDouble().toString();
}
// [toString] will represent very small numbers in exponential form.
// Instead use [toStringAsFixed] with the maximum number of fractional
// digits.
var s = toStringAsFixed(20);
// [toStringAsFixed] will still represent very large numbers in
// exponential form.
if (s.contains('e')) {
// Ignore values in exponential form.
return s;
}
// Ignore unrecognized values (e.g. NaN, +infinity, -infinity).
var i = s.indexOf('.');
if (i == -1) {
return s;
}
return s.substring(0, i + fractionDigits + 1);
}
}
void main() {
var values = [
1.151,
1.15,
1.1999,
-1.1999,
1.0,
1e21,
1e-20,
double.nan,
double.infinity,
double.negativeInfinity,
];
for (var v in values) {
print(v.toStringAsTruncated(1));
}
}
Another approach one might consider is to multiply by pow(10, fractionalDigits), use double.truncateToDouble, divide by the power-of-10 used earlier, and then use .toStringAsFixed(fractionalDigits). That could work for human-scaled values, but it could generate unexpected results for very large values due to precision loss from floating-point arithmetic. (This approach would work if you used package:decimal instead of double, though.)
1 Not rounding seems especially bad given that using doubles to represent fractional base-10 numbers is inherently imprecise. For example, since the closest IEEE-754 double-precision floating number to 0.7 is 0.6999999999999999555910790149937383830547332763671875, do you really want 0.7.toStringAsTruncated(1) to return '0.6' instead of '0.7'?

16 bit logic/computer simulation in Swift

I’m trying to make a basic simulation of a 16 bit computer with Swift. The computer will feature
An ALU
2 registers
That’s all. I have enough knowledge to create these parts visually and understand how they work, but it has become increasingly difficult to make larger components with more inputs while using my current approach.
My current approach has been to wrap each component in a struct. This worked early on, but is becoming increasingly difficult to manage multiple inputs while staying true to the principles of computer science.
The primary issue is that the components aren’t updating with the clock signal. I have the output of the component updating when get is called on the output variable, c. This, however, neglects the idea of a clock signal and will likely cause further problems later on.
It’s also difficult to make getters and setters for each variable without getting errors about mutability. Although I have worked through these errors, they are annoying and slow down the development process.
The last big issue is updating the output. The output doesn’t update when the inputs change; it updates when told to do so. This isn’t accurate to the qualities of real computers and is a fundamental error.
This is an example. It is the ALU I mentioned earlier. It takes two 16 bit inputs and outputs 16 bits. It has two unary ALUs, which can make a 16 bit number zero, negate it, or both. Lastly, it either adds or does a bit wise and comparison based on the f flag and inverts the output if the no flag is selected.
struct ALU {
//Operations are done in the order listed. For example, if zx and nx are 1, it first makes input 1 zero and then inverts it.
var x : [Int] //Input 1
var y : [Int] //Input 2
var zx : Int //Make input 1 zero
var zy : Int //Make input 2 zero
var nx : Int //Invert input 1
var ny : Int //Invert input 2
var f : Int //If 0, do a bitwise AND operation. If 1, add the inputs
var no : Int //Invert the output
public var c : [Int] { //Output
get {
//Numbers first go through unary ALUs. These can negate the input (and output the value), return 0, or return the inverse of 0. They then undergo the operation specified by f, either addition or a bitwise and operation, and are negated if n is 1.
var ux = UnaryALU(z: zx, n: nx, x: x).c //Unary ALU. See comments for more
var uy = UnaryALU(z: zy, n: ny, x: y).c
var fd = select16(s: f, d1: Add16(a: ux, b: uy).c, d0: and16(a: ux, b: uy).c).c //Adds a 16 bit number or does a bitwise and operation. For more on select16, see the line below.
var out = select16(s: no, d1: not16(a: fd).c, d0: fd).c //Selects a number. If s is 1, it returns d1. If s is 0, it returns d0. d0 is the value returned by fd, while d1 is the inverse.
return out
}
}
public init(x:[Int],y:[Int],zx:Int,zy:Int,nx:Int,ny:Int,f:Int,no:Int) {
self.x = x
self.y = y
self.zx = zx
self.zy = zy
self.nx = nx
self.ny = ny
self.f = f
self.no = no
}
}
I use c for the output variable, store values with multiple bits in Int arrays, and store single bits in Int values.
I’m doing this on Swift Playgrounds 3.0 with Swift 5.0 on a 6th generation iPad. I’m storing each component or set of components in a separate file in a module, which is why some variables and all structs are marked public. I would greatly appreciate any help. Thanks in advance.
So, I’ve completely redone my approach and have found a way to bypass the issues I was facing. What I’ve done is make what I call “tracker variables” for each input. When get is called for each variable, it returns that value of the tracker assigned to it. When set is called it calls an update() function that updates the output of the circuit. It also updates the value of the tracker. This essentially creates a ‘copy’ of each variable. I did this to prevent any infinite loops.
Trackers are unfortunately necessary here. I’ll demonstrate why
var variable : Type {
get {
return variable //Calls the getter again, resulting in an infinite loop
}
set {
//Do something
}
}
In order to make a setter, Swift requires a getter to be made as well. In this example, calling variable simply calls get again, resulting in a never-ending cascade of calls to get. Tracker variables are a workaround that use minimal extra code.
Using an update method makes sure the output responds to a change in any input. This also works with a clock signal, due to the architecture of the components themselves. Although it appears to act as the clock, it does not.
For example, in data flip-flops, the clock signal is passed into gates. All a clock signal does is deactivate a component when the signal is off. So, I can implement that within update() while remaining faithful to reality.
Here’s an example of a half adder. Note that the tracker variables I mentioned are marked by an underscore in front of their name. It has two inputs, x and y, which are 1 bit each. It also has two outputs, high and low, also known as carry and sum. The outputs are also one bit.
struct halfAdder {
private var _x : Bool //Tracker for x
public var x: Bool { //Input 1
get {
return _x //Return the tracker’s value
}
set {
_x = x //Set the tracker to x
update() //Update the output
}
}
private var _y : Bool //Tracker for y
public var y: Bool { //Input 2
get {
return _y
}
set {
_y = y
update()
}
}
public var high : Bool //High output, or ‘carry’
public var low : Bool //Low output, or ‘sum’
internal mutating func update(){ //Updates the output
high = x && y //AND gate, sets the high output
low = (x || y) && !(x && y) //XOR gate, sets the low output
}
public init(x:Bool, y:Bool){ //Initializer
self.high = false //This will change when the variables are set, ensuring a correct output.
self.low = false //See above
self._x = x //Setting trackers and variables
self._y = y
self.x = x
self.y = y
}
}
This is a very clean way, save for the trackers, do accomplish this task. It can trivially be expanded to fit any number of bits by using arrays of Bool instead of a single value. It respects the clock signal, updates the output when the inputs change, and is very similar to real computers.

Swift .isNaN Understand how it works

I am currently facing an issue in understanding how .isNan works.
I am maintaining an application which is not developed (in Swift 2.3) by myself.
We have a nice amount of crashes from this code, and from my understanding I don't understand how.
Here is the method, which is simply a format method in order to set the appropriate value to your label by testing different cases.
static func formatFloat(float: Float?, withMaxDigits
max: Int, andUnit unit: String) -> String {
var label: String = "-"
if let float = float {
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
numberFormatter.minimumFractionDigits = 0
numberFormatter.maximumFractionDigits = max
numberFormatter.roundingMode = .RoundHalfUp
if !float.isNaN {
var formattedValue = numberFormatter.stringFromNumber(float)!
if(formattedValue == "-0")
{
formattedValue = "0"
}
label = "\(formattedValue) \(unit)"
}
}
return label
}
Am I right that it justs check to determine whether a value is NaN or not, in order to test everything, and set the text accordingly ?
I read some posts/documentations and I don't understand this :
In some languages NaN != NaN, but this isn't the case in Cocoa.
What about nil and NaN ? I mean isNan check for false right ?
The IEEE floating point spec documents certain bit patterns that represent NaN invalid results.
nil is different from a NaN. In Swift, only an optional can contain nil, and it indicates the absence of a value.
a NaN means you performed some operation that resulted in an invalid result. You should check the isNaN property to see if a number contains a NaN.
Edit:
Note that there are different values that are marked as NaN, so one .NaN value may not be equal to another .NaN.
No, nan is a value that a floating point can take. nil can only be taken by optional vars. Also I'm not sure where you got that quote, but .nan == .nan is false. For more information read https://developer.apple.com/reference/swift/floatingpoint

Generation random (positive and negative) numbers for a quiz

I am writing a Math Quiz app for my daughter in xcode/swift.Specifically, I want to produce a question that will contain at least one negative number to be added or subtracted against a second randomly generated number.Cannot be two positive numbers.
i.e.
What is (-45) subtract 12?
What is 23 Minus (-34)?
I am struggling to get the syntax right to generate the numbers, then decide if the said number will be a negative or positive.
Then the second issue is randomizing if the problem is to be addition or subtraction.
It's possible to solve this without repeated number drawing. The idea is to:
Draw a random number, positive or negative
If the number is negative: Draw another number from the same range and return the pair.
If the number is positive: Draw the second number from a range constrained to negative numbers.
Here's the implementation:
extension CountableClosedRange where Bound : SignedInteger {
/// A property that returns a random element from the range.
var random: Bound {
return Bound(arc4random_uniform(UInt32(count.toIntMax())).toIntMax()) + lowerBound
}
/// A pair of random elements where always one element is negative.
var randomPair: (Bound, Bound) {
let first = random
if first >= 0 {
return (first, (self.lowerBound ... -1).random)
}
return (first, random)
}
}
Now you can just write...
let pair = (-10 ... 100).randomPair
... and get a random tuple where one element is guaranteed to be negative.
Here's my attempt. Try running this in a playground, it should hopefully get you the result you want. I hope I've made something clean enough...
//: Playground - noun: a place where people can play
import Cocoa
let range = Range(uncheckedBounds: (-50, 50))
func generateRandomCouple() -> (a: Int, b: Int) {
// This function will generate a pair of random integers
// (a, b) such that at least a or b is negative.
var first, second: Int
repeat {
first = Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound))) - range.upperBound
second = Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound))) - range.upperBound
}
while (first > 0 && second > 0);
// Essentially this loops until at least one of the two is less than zero.
return (first, second)
}
let couple = generateRandomCouple();
print("What is \(couple.a) + (\(couple.b))")
// at this point, either of the variables is negative
// I don't think you can do it in the playground, but here you would read
// her input and the expected answer would, naturally, be:
print(couple.a + couple.b)
In any case, feel free to ask for clarifications. Good luck !

Get y-value of points along the generated line graph in Highcharts

I have two series of data--one consists of (Date, Rating), and the other is a list of events that happened on specific dates. The ultimate goal is to use the first series of data to construct a line graph to show how the rating has changed over time, which I've done successfully:
I now need to plot the second set of data using the dates as x-values (different dates than the first set), but want them to show up on the line--meaning I need to get the y-value of what that date would be if it were in the first set. I hope I explained that clearly; let me know if it's confusing.
I forgot I knew how to do algebra.
function getYValue(dataset, date){
//gets rating estimate for closest surrounding dates using algebraic fun-times
var point_1, point_2;
for (j = 0; j < dataset.length; j++){
if (dataset[j][0] > date) {
point_1 = dataset[j-1];
point_2 = dataset[j];
break;
}
}
var slope = (point_2[1] - point_1[1]) / (point_2[0] - point_1[0]);
var rating = slope * (date - point_2[0]) + point_2[1];
return rating;
}

Resources