You are not logged in.

#1 2017-03-15 14:18:54

JohnBobSmith
Member
From: Canada
Registered: 2014-11-29
Posts: 804

ConvertIt! - A simple CLI measurement converter

Hello all,

I've busy working on a small utility to convert temperatures and measurements. Github link: https://github.com/JohnBobSmith/convertit-git Supported conversions are Fahrenheit, Kelvin, and Celsius within each-other. The most common metric to imperial and vice versa are also supported at this time. So, why ConvertIt? To quote my README:

ConvertIt!'s README wrote:

ConvertIt! was created because of a couple of reasons:
1) I wanted to be able to convert outputs from other programs (more on that later).
2) I wanted to be able to convert stuff without an internet connection. Why Google it when you can ./convertit
3 )I wanted to have conversions all in one place. This makes life easier to the user, in my opinion.
4) I wanted a change from my game programming, and I thought that a utlity would be a great thing to write.

In particular, I wanted to be able to convert temperature outputs using the standard input, as per point one. Example below:

[jbs@dmb-gaming-laptop ~]$ inxi -Fxz | grep Temp
Sensors:   System Temperatures: cpu: 44.4C mobo: N/A gpu: 42.0
[jbs@dmb-gaming-laptop ~]$ inxi -Fxz | grep Temp | cut -c 38-41 | convertit -C
110.3[jbs@dmb-gaming-laptop ~]$ 

We can now use 110.3 degrees Fahrenheit in something like, say. conky, if one so desired. The programs output is designed to be very clean. One can optionally pass -U or -u to use the unit symbols. C for Celsius, F for Fahrenheit, etc. etc. It's worth mentioning that I've found a bug with -U and -u while writing this post, which will be fixed right away. wink

I've also wrote up a PKGBUILD (included in the repository)

# Maintainer: David "JohnBobSmith" Bogner <myrunescapeemail609 AT gmail DOT com>
pkgname=convertit-git
pkgver=r10.4bed830
pkgrel=1
pkgdesc="A small utility for converting measurements (Temperature, Metric, Imperial)"
arch=(x86_64)
makedepends=('git')
url="https://github.com/JohnBobSmith/convertit-git"
license=('MIT')
source=("git+https://github.com/JohnBobSmith/convertit-git.git")
md5sums=('SKIP')

pkgver() {
  cd "$pkgname"
  printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}

build() {
	cd "$pkgname/src/"
	make
}

package() {
	cd "$pkgname"
	install -D -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
	install -D -m755 "src/convertit" "${pkgdir}/usr/bin/convertit"
}

And a Makefile is present in src/ for your convenience.:)

My reason for posting here, other than to of course share and learn something new, was to get feedback on the program. What conversions would you like added? Bugs, questions, feedback of any sort positive or negative is all welcome, providing I learn something from it. I look forward to hearing what you guys think! big_smile


I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.

Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...

Offline

#2 2017-03-15 15:21:19

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,412
Website

Re: ConvertIt! - A simple CLI measurement converter

I've only started with C++ since late last year, so take this with a grain of salt...

https://github.com/JohnBobSmith/convert … c/main.cpp

* I'd probably go with std::cerr for informational messages. See man stdout.
* You can use a single std::cout instead of repeating it per line (probably only stylistic)
* Consider some library for option handling instead of your own adhoc implementation. If it were C, I'd say getopt(3).

https://github.com/JohnBobSmith/convert … rature.cpp
https://github.com/JohnBobSmith/convert … Metric.cpp
https://github.com/JohnBobSmith/convert … perial.cpp
+ assorted headers

* Since we're in C++ and have all the power of templates at our disposal, I'd use them instead of hardcoding float. (In C11 we'd use generic selections)
* Some of the code could be shortened by using the ternary operator. Seems to be a love/hate thing for C programmers...

Last edited by Alad (2017-03-15 15:23:59)


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3 2017-03-15 15:24:14

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: ConvertIt! - A simple CLI measurement converter

Also worth taking a look at units in [community].


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#4 2017-03-15 21:35:26

JohnBobSmith
Member
From: Canada
Registered: 2014-11-29
Posts: 804

Re: ConvertIt! - A simple CLI measurement converter

Go figure there already exists a program for this purpose. But the point is to try and learn something. I might have to experiment with getopt() because I agree my implementation for parsing CLI arguments is... bad. I had no idea there was a man page fro stdout, thats awesome! I have yet to bother with templates, but that might be worth experimenting with. The ternary operator might be useful. I'll have to see how much my farm work picks up or declines before continuing much further with this. Thanks for the input!


I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.

Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...

Offline

#5 2017-03-17 00:35:26

ajbibb
Member
Registered: 2012-02-12
Posts: 142

Re: ConvertIt! - A simple CLI measurement converter

Few things for what they are worth (and it may not be much - I'm not an expert)

1)  You've got a bunch of divide by zero checks that are not needed because when you do the math you are dividing by a constant with no chance of dividing by zero.  In fact the implementation of adding 0.1 in the case of the input being zero just increases the error in the conversion for that special case.

2)  Personally I would remove the magic numbers (for instance 0.404685642 in the acres/hectares functions) and replace them with a named constant.  I'd also put the constants in a single file, probably a header file.  Again that is just me. 

3)  My personal preference is not to declare a variable just to return it, just return the answer.  For instance not:

    float acres = hectares / 0.404685642;
    return acres;

but:

return hectares / 0.404685642;

4) Related to #3 above is that most of the functions could be inline if you wanted.

5) For conversions I'm wondering if maybe using capital and lower case letters to indicate the direction may make sense.  For instance capital for metric to imperial, lower for imperial to metric. Of course if you start getting into conversions within a system (feet->miles, kilometers->meters) then that won't work.  I haven't really thought it through, but that was the first thing that popped into my head when I looked at your front page on github. 

I'll repeat, I'm not an expert and the programming suggestions are just ways I'd do it. Use, consider, or ignore as you want.  I think programming style is a very personal matter so do what you feel works best for you.

Offline

#6 2017-03-17 18:01:29

JohnBobSmith
Member
From: Canada
Registered: 2014-11-29
Posts: 804

Re: ConvertIt! - A simple CLI measurement converter

I've taken a look at units and I really don't like its output:

[jbs@dmb-gaming-laptop ~]$ units 15km mi
        * 9.3205679
        / 0.1072896
[jbs@dmb-gaming-laptop ~]$ 

That output just seems... awful in my opinion and my opinion only. I really want to have a setup where it gives me the direct conversion without the math. See my original post.

It just so happens I'll also have a (small) break in farm work. Therefore, I'll continue to work on this. I have a *lot* of improvements to do. Check the github page regularly if so desired. I'll post back when I have made some major change IE using a library to get CLI arguments. I'll start with that.

@ajbibb
Thanks for the input! I'm not a huge fan of inlined functions... However, the way that you did it made a lot of sense. I'll experiment with that and see if it meets my needs. Named constants would also be something worth looking into. For the conversions, I've tried to use cli arguments that "make sense". For instance, C is always Celsius, F is always Fahrenheit. But I really like your idea of capital letters = metric to imperial and lowercase = imperial to metric. That's a great idea. Lots of stuff to think about now hehe smile

EDIT: Wow, using getopt() was easier than I thought it world be. Switching to getopt() torched nearly 70 lines of code! https://github.com/JohnBobSmith/convert … 036c34d958. Do let me know if I forgot to add a break; somewhere XD.

Last edited by JohnBobSmith (2017-03-17 19:08:35)


I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.

Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...

Offline

#7 2017-03-18 01:40:25

Steef435
Member
Registered: 2013-08-29
Posts: 577
Website

Re: ConvertIt! - A simple CLI measurement converter

Well I'll also pretend I know what I'm doing and comment a bit then ^^

- You use Metirc.h instead of Metric.h (typo)
- C++ has a bool type, so you can use that for useUnitSymbols
- ajbibb's point about the division by zero makes your life a lot easier

If I were you, if I were using C++, I'd be getting as dirty as I could and probably use lambdas for the conversion functions and store them in a way somewhat like this:

struct Conversion {
        std::string from;
        std::string to;
        std::function<double(double)> conversion;
};

const double CELSIUS_TO_FAHRENHEIT = 3.4;

const Conversion CONVERSIONS[] = {
        { "celsius", "fahrenheit", [](auto c) { return c * CELSIUS_TO_FAHRENHEIT; } },
        { "fahrenheit", "celsius", [](auto f) { return f / CELSIUS_TO_FAHRENHEIT; } },
        ...
};

Even uglier (pretty from a C++ standpoint, also from the optimization standpoint but that's negligible in this case), use two maps to map a unit to a map mapping target units to a lambda doing the conversion. Then you can do something like this: conversions["celsius"]["fahrenheit"](23); to convert 23 from Celsius to Fahrenheit. If you do this, make the maps constant and use the initializer list constructor (which saves a lot of typing).

Even more ugly, change the names to their representation on the command line. Say, the command-line syntax is <From> <To> <Input>, e.g. ./convertit C F 23 to convert 23 from Celsius to Fahrenheit. Then make sure "celsius" in the map above is "C" and "fahrenheit" "F".

Then you basically only have to do something like this:

int main(int argc, char** argv) {
    std::cout << conversions[argv[1]][argv[2]](string_to_double(argv[3])) << std::endl;
}

(of course, input and error checking is needed as well)


Prettier would be to use e.g. an enum class for the units, and then map strings to certain units in some way ("celsius" => Unit::CELSIUS, "C" => Unit::CELSIUS, "F" => Unit::FAHRENHEIT, ...)


I may be completely wrong though, I'm not a Programmer (TM), let alone a C++ Guru (TM).

Have fun with your project!

Last edited by Steef435 (2017-03-18 01:44:39)

Offline

#8 2017-03-18 20:41:27

JohnBobSmith
Member
From: Canada
Registered: 2014-11-29
Posts: 804

Re: ConvertIt! - A simple CLI measurement converter

Steef, I think you're way over engineering the project. I've corrected the typo though, good catch there. I'll also remove any extraneous divide by zero checks. I suppose a bool would also work better for _USE_UNIT_SYMBOLS. I'll see about that one. My argument "syntax" is that the input argument is the one given, expecting an output based on the help table. So -C is Celsius as input to Fahrenheit (per the help table) as output. I'll post back once I've made some more corrections. smile

EDIT: Converted useUnitSymbols from int to bool. Amen for control + R! https://github.com/JohnBobSmith/convert … 617cd62f5d

Last edited by JohnBobSmith (2017-03-18 21:12:25)


I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.

Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...

Offline

Board footer

Powered by FluxBB