• LetMeFinclOut (unregistered) in reply to Ol' Bob
    Ol' Bob:
    snoofle:
    Ben Jammin:
    Yeah, this could be drastically improved with a switch statement.
    Not enterprisey enough; what if they need the values in different bases? Needs XML:
    <?xml version="1.0" encoding="UTF-8"?>
    <doc>
       <Fractions>
          <value>
             <reading>1.0"</reading>
             <percentDecimal>100.0%</percentDecimal>
             <percentOctal>144.0%</percentOctal>
             <percentHex>64.0%</percentHex>
             <percentBinary>1100100.0%</percentBinary>
          </value>
          <value>
             <reading>.999"</reading>
             <percentDecimal>99.9%</percentDecimal>
             ...
          </value>
          ...
          <value>
             <reading>0.01</reading>
             <percentDecimal>1.0%</percentDecimal>
             ...
          </value>
          ...
          <value>
             <reading>0.001</reading>
             <percentDecimal>0.1%</percentDecimal>
             ...
          </value>
          <value>
             <reading>0</reading>
             <percentDecimal>Your battery has no power - you can't see this</percentDecimal>
             ...
          </value>
       </Fractions>
    </doc>
    

    [Edit] RichP - you just beat me to it

    ROFLMAO!!!!

    Indeed. This may be the Rube Goldberg of percent calculations.

  • (cs) in reply to Yaos
    Yaos:
    This is what we in the business call "paid by the line".
    Indeed. If he was a Real Programmer, this would have all been generated by a one-liner.

    Oh wait, it could be.

    But probably not by this guy....

  • (cs)

    Is it weird that I feel the need for caffiene after reading that small bit of code?

    Schizer if that is the good part I am slightly morbidly fasinated on what the rest of the code looks like.

  • Dirk (unregistered)

    Seriously, can I take him into the middle of a paddock and shoot him?

  • (cs)
    There is hardly anything in the world that some man cannot make a little worse and sell a little cheaper, and the people who consider price only are this man's lawful prey. -John Ruskin

    There is hardly [any program] in the world that some man [with lesser skill] cannot make a little worse and [be paid a little less], and the [management that] considers price only [deserves what it gets].

  • (cs) in reply to Frist
    Frist:
    Frist ...

    My brain hurts

    +1

  • Ken B. (unregistered) in reply to renewest
    renewest:
    Mathematical calculations drain the battery too much.
    And, given that the checks are high-to-low, this code will drain the battery faster the lower the power is.
  • Ken B. (unregistered) in reply to Mr. Blutarsky
    Mr. Blutarsky:
    What if the battery power is 0.0?
    Hence this code at the bottom:
    Else
        Return "NA"
  • Ken B. (unregistered) in reply to Schmitter
    Schmitter:
    I am 100% sure there is a better way to do that.
    If Schmitter.code.isAvailable(compareBetter).toString == "True"
    Then
        Return "100%"
    Else
        Return "NA"
    EndIf
  • Tasty (unregistered) in reply to BentFranklin
    BentFranklin:
    The funniest thing is that it runs the method SystemInformation.PowerStatus.BatteryLifePercent.ToString so many times that it could actually drain the battery by 1% in the middle of the function and give the wrong answer. Or, if the battery is charging, it could skip the right answer and fall all the way down to "NA".

    Heisenberg computing! The act of watching the battery life changes it.

  • Mike (unregistered)

    This is actually very clever, because it ensures that if the returned value is unexpected (-1 for example), you don't get a strange readout, but instead get a simple "NA".

    Think of all the Error'd we get here with -99999 temperatures etc. This code is invulnerable to such defects.

  • tgdavies (unregistered) in reply to jdw

    Why did you only change five cases?

  • Argle (unregistered) in reply to PedanticCurmudgeon
    PedanticCurmudgeon:
    Argle:
    Ben Jammin:
    Yeah, this could be drastically improved with a switch statement.
    Seen it... though admittedly by a student... though still not excused. Spent an hour discussing C string library and giving examples of all the basics. Gave an assignment to read in lines of text and convert to all uppercase. Everyone else does the 5-10 line program but one thought the whole thing should be an exercise in making a very big switch statement based on the letters on the line.
    Hopefully someone suggested that the student choose a different major (assuming the class wasn't an elective).
    Somehow he thought the problem was me. I'm not sure why: 20 other people in the class used the strupr() call I demonstrated in class.

    If you CAN teach programming, I encourage anyone to do a little. It gives you the opportunity to give some wisdom to others... and you learn some fairly interesting things. The last classes I taught had an influx of quite a few young men who thought computer programming just had to be dead-easy and so they signed up for programming classes. Why did they reach this conclusion? Because they saw the same commercial I saw for some programming school that featured a couple college guys on a couch playing video games basically saying "computer programming is easy!" They were literally convincing students to come take programming classes (at their school with government grant money, of course) because it was the same as playing video games. I was aghast at the commercial. Speechless when several students affected by the ads showed up in my classes.

  • Argle (unregistered) in reply to Craven Weasel
    Craven Weasel:
    Matt:
    looks like VB to me... and for some reason VB does not have ==

    Captcha: oppeto - pedo op?

    Some reason? Is it becuase it descends from a (admittedly horrible) language that predates C?

    The =/== silliness was introduced by Ken Thompson/and or Dennis Ritchie when they implemented "B", even though it was supposed to be derived from BCPL which seems to used the then conventional ALGOL style = for equality, and := for assignment.

    For some reason they changed this, and introduced a myrid of unintended behaviours (bugs) and Yoda conditonals upon the world, as well as making a generation of Pascal trained programmers (like me) brains explode when they first saw it (why oh why oh why?)

    Note - I'm not denigrating C - it's great for some things, only an abritary design decision made in the late 60s.

    As I recall, they did a survey of operations and found that assignment was used at least twice as often as comparisons for equality, so they opted for shorter symbology for assignment.

  • (cs) in reply to Argle
    Argle:
    Craven Weasel:
    Matt:
    looks like VB to me... and for some reason VB does not have ==

    Captcha: oppeto - pedo op?

    Some reason? Is it becuase it descends from a (admittedly horrible) language that predates C?

    The =/== silliness was introduced by Ken Thompson/and or Dennis Ritchie when they implemented "B", even though it was supposed to be derived from BCPL which seems to used the then conventional ALGOL style = for equality, and := for assignment.

    For some reason they changed this, and introduced a myrid of unintended behaviours (bugs) and Yoda conditonals upon the world, as well as making a generation of Pascal trained programmers (like me) brains explode when they first saw it (why oh why oh why?)

    Note - I'm not denigrating C - it's great for some things, only an abritary design decision made in the late 60s.

    As I recall, they did a survey of operations and found that assignment was used at least twice as often as comparisons for equality, so they opted for shorter symbology for assignment.

    As good an excuse as any, I suppose. Just like Y2K, "saving bytes" has caused us more pain than all other programming WTF's combined.

  • (cs) in reply to FTFY
    FTFY:
    Matt Westwood:
    Mozhet buyt ti krasivaya, na u menya zhenschina.
    может быть ты красивая но у меня женщина
    Ochen khorosho.
  • DonaldK (unregistered) in reply to Stabbitha
    Stabbitha:
    Obligatory "The real WTF is VB..."

    Now back to getting paid to write VB ... sigh ...

    You realise it's 2012...? I honestly hope you're not referring to VB6.

    O bother that's worse than those who were being paid for COBOL programming for Y2K fixes...

  • Neil Morrison (unregistered) in reply to DonaldK

    I worked with people who would read this information from an Oracle table.

    An INDEXED Oracle table!

    Brainy hurty much.

  • (cs) in reply to ZSXcv
    ZSXcv:
    So....he's improved the solution (by making it work and be more succinct) and you complain? Methinks you are a turd.
    I wasn't complaining — I was simply explaining why his code wouldn't produce the exact same results as the original, after someone else pointed this out. I'd be all for simply converting directly to a percentage and returning that.
  • Gibbon1 (unregistered) in reply to PedanticCurmudgeon
    PedanticCurmudgeon:
    slamers:
    Maybe we need to start forcing programmers to have a license to be able to operate - just like we do for many other professions. This person would definitely have to have their license suspended for at least a year!
    That depends on who is appointed to the licensing board. If the licensing board were full of bad programmers, we might have our licenses suspended for using design patterns.

    If you had a licensing board, then you'd have to know PL/I, COBOL and FORTRAN IV. Your license would also only be good in the state it was issued in. To get it would require 2000 hours of program design, vs just coding while working for licensed programmer.

  • Bionic Slacker (unregistered)

    If any coder that I ever work on a project with ever checks code like this into the project repository, I'm going to calmly walk over to his cubicle and put a bullet through his head.

    Whoever did this does not deserve to live.

  • (cs) in reply to jdw
    jdw:
    What awful code. I mean, he should have assigned SystemInformation.PowerStatus.BatteryLifePercent.ToString to a variable first. That would have saved him a bunch of typing. Here are some comparison snippets:
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.2" Then
                Return "20%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.19" Then
                Return "19%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.18" Then
                Return "18%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.17" Then
                Return "17%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.16" Then
                Return "16%"
    	ElseIf BatteryLifePercentString = "0.2" Then
                Return "20%"
            ElseIf BatteryLifePercentString = "0.19" Then
                Return "19%"
            ElseIf BatteryLifePercentString = "0.18" Then
                Return "18%"
            ElseIf BatteryLifePercentString = "0.17" Then
                Return "17%"
            ElseIf BatteryLifePercentString = "0.16" Then
                Return "16%"

    It would also avoid querying the system for battery state 100 times...

  • (cs) in reply to Argle
    Argle:
    PedanticCurmudgeon:
    Argle:
    Seen it... though admittedly by a student... though still not excused. Spent an hour discussing C string library and giving examples of all the basics. Gave an assignment to read in lines of text and convert to all uppercase. Everyone else does the 5-10 line program but one thought the whole thing should be an exercise in making a very big switch statement based on the letters on the line.
    Hopefully someone suggested that the student choose a different major (assuming the class wasn't an elective).
    Somehow he thought the problem was me. I'm not sure why: 20 other people in the class used the strupr() call I demonstrated in class.
    At least you're in the position of being able to call him out in front of the class to discuss his code. “I have good news and bad news. The good news is that we can be sure that your code is not plagiarized. The bad news — for you — is that this is because the code in question is so bad it could only have been written by an utter moron who didn't pay any attention at all. Class, be aware that you can fall into the trap of being nearly as stupid if you don't think through what you're doing…”

    Also remember that anyone that stupid can be failed and kicked out. While yes, the school might not be too happy at losing the income, they'll support getting rid of idiots as they're all to likely to cause problems in lots of other classes too. Why have a moron when you can have three ordinary students for the same teaching effort?

  • ClaudeSuck.de (unregistered) in reply to PedanticCurmudgeon

    [quote user="PedanticCurmudgeon"][quote user="slamers"]If the licensing board were full of bad programmers, we might have our licenses suspended for using design patterns.[/quote]

    ...because nobody is using them, anywayz.

    That would redefine the term good/bad programmer (developer?)

  • ClaudeSuck.de (unregistered) in reply to Stabbitha
    Stabbitha:
    Obligatory "The real WTF is VB..."

    Now back to getting paid to write VB ... sigh ...

    Right now I am maintaing a VB6 application for supermarkets. Sadly enough, it is well written. However I can say: TRWTF is in the database (which is SQLServer, hence MS, hence...)

    captcha: caecus, is this a new form of feces?

  • ClaudeSuck.de (unregistered) in reply to jdw
    jdw:
    What awful code. I mean, he should have assigned SystemInformation.PowerStatus.BatteryLifePercent.ToString to a variable first. That would have saved him a bunch of typing. Here are some comparison snippets:
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.2" Then
                Return "20%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.19" Then
                Return "19%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.18" Then
                Return "18%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.17" Then
                Return "17%"
            ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.16" Then
                Return "16%"
    	ElseIf BatteryLifePercentString = "0.2" Then
                Return "20%"
            ElseIf BatteryLifePercentString = "0.19" Then
                Return "19%"
            ElseIf BatteryLifePercentString = "0.18" Then
                Return "18%"
            ElseIf BatteryLifePercentString = "0.17" Then
                Return "17%"
            ElseIf BatteryLifePercentString = "0.16" Then
                Return "16%"

    and he wouldn't have called the same function 99 times (in the worst case)

  • ClaudeSuck.de (unregistered) in reply to NPSF3000
    NPSF3000:
    Whatever:
    Do you think he wrote a program to automatically generate the code?

    I refer you to my earlier comment:

    http://thedailywtf.com/Comments/The-Percent-Conversion.aspx#373594

    Just because you insisted: you are using the LINQ library but I can't see why.

  • default_ex (unregistered) in reply to DonaldK
    DonaldK:
    renewest:
    Mathematical calculations drain the battery too much.

    Quite. Storage for big binaries is not an issue these days, and heavy mathematical calculations (such as multiplying by 100 and rounding / trimming) cause high CPU usage, which warms up our planet. We should do our part against global warming...

    Pretty sure a bunch of failed 'if' statements will consume more power than "Math.Trunc(battery life * 100)" or "(int)(battery life * 100)".

  • NPSF3000 (unregistered) in reply to ClaudeSuck.de
    ClaudeSuck.de:
    NPSF3000:
    Whatever:
    Do you think he wrote a program to automatically generate the code?

    I refer you to my earlier comment:

    http://thedailywtf.com/Comments/The-Percent-Conversion.aspx#373594

    Just because you insisted: you are using the LINQ library but I can't see why.

    Because that's automatically generated by the IDE, and not worth the time to remove.

    I am surprised through that you only noticed the System.Linq as being extraneous while both System.Text and System.Collections.Generic are equally unused.

  • Is that a suppository up my ass or are you just happy to see me? (unregistered) in reply to Gurth
    Gurth:
    ZSXcv:
    So....he's improved the solution (by making it work and be more succinct) and you complain? Methinks you are a turd.
    I wasn't complaining — I was simply explaining why his code wouldn't produce the exact same results as the original, after someone else pointed this out. I'd be all for simply converting directly to a percentage and returning that.
    A TURD! HA! I eat turds for breakfast!
  • (cs) in reply to ClaudeSuck.de
    ClaudeSuck.de:
    PedanticCurmudgeon:
    If the licensing board were full of bad programmers, we might have our licenses suspended for using design patterns.

    ...because nobody is using them, anywayz.

    That would redefine the term good/bad programmer (developer?)

    I worked in a team where the boss was very proud that he had a team member who was an "accredited programmer", having gone through some officially-recognised (and probably expensive) series of training courses. His colleagues were less impressed with this guy's credentials, as his code was severely substandard. He knew the techniques (as they had been taught) but was a dunce at applying any form of analytical thinking to the tasks he was assigned.

    Example: he implemented a generic comparator method (so as to be able to sort a table of variegated java objects) as a series of bubble-sorts surrounded by if-thens of almost as high a quality as today's exemplar. The only difference between those bubble-sorts was the objects on which they were operating. And what made this particular class even more worthy of ridicule, he had cited the name and serial number of the course in which said bubble-sort had been taught. The trouble is, we had no incentive to replace it with something more sensible because it worked and we had no need at that time to expand it.

  • (cs) in reply to default_ex
    default_ex:
    DonaldK:
    renewest:
    Mathematical calculations drain the battery too much.

    Quite. Storage for big binaries is not an issue these days, and heavy mathematical calculations (such as multiplying by 100 and rounding / trimming) cause high CPU usage, which warms up our planet. We should do our part against global warming...

    Pretty sure a bunch of failed 'if' statements will consume more power than "Math.Trunc(battery life * 100)" or "(int)(battery life * 100)".

    Is anybody willing to produce some metrics?

  • (cs) in reply to Matt Westwood
    Matt Westwood:
    FTFY:
    Matt Westwood:
    Mozhet buyt ti krasivaya, na u menya zhenschina.
    может быть ты красивая но у меня женщина
    Ochen khorosho.
    OK, but why the sudden interest in learning Russian?
  • Shinobu (unregistered) in reply to Argle
    Argle:
    Craven Weasel:
    Matt:
    ... for some reason VB does not have ==
    ... The =/== silliness was introduced by Ken Thompson/and or Dennis Ritchie when they implemented "B", even though it was supposed to be derived from BCPL which seems to use ... = for equality, and := for assignment. For some reason they changed this, and introduced a myriad of ... (bugs) and Yoda conditonals upon the world, ...
    As I recall, they did a survey of operations and found that assignment was used at least twice as often as comparisons for equality, so they opted for shorter symbology for assignment.
    Meanwhile, in VB you don't need := or == since it's always clear from context which is meant. You don't assign in expressions, and a comparison can never be a statement. It makes sense, is clear, you can always use =, and you never get weird bugs from accidentally using = instead of ==.
  • acsi acsi (unregistered)

    This is brilliant. Everybody knows your battery is like almost full and then studdenly drops half way your call to empty. This table mitigates for that. I can give different percentages depending on what value you get. I should have thought of it!

  • (cs) in reply to Shinobu
    Shinobu:
    Meanwhile, in VB you don't need := or == since it's always clear from context which is meant. You can't assign in expressions, and a comparison can never be a statement. It makes sense, is clear, you can always use =, and you never get weird bugs from accidentally using = instead of ==.
    FTFY
  • ClaudeSuck.de (unregistered) in reply to Shinobu
    Shinobu:
    Argle:
    Craven Weasel:
    Matt:
    ... for some reason VB does not have ==
    ... The =/== silliness was introduced by Ken Thompson/and or Dennis Ritchie when they implemented "B", even though it was supposed to be derived from BCPL which seems to use ... = for equality, and := for assignment. For some reason they changed this, and introduced a myriad of ... (bugs) and Yoda conditonals upon the world, ...
    As I recall, they did a survey of operations and found that assignment was used at least twice as often as comparisons for equality, so they opted for shorter symbology for assignment.
    Meanwhile, in VB you don't need := or == since it's always clear from context which is meant. You don't assign in expressions, and a comparison can never be a statement. It makes sense, is clear, you can always use =, and you never get weird bugs from accidentally using = instead of ==.

    and that's why

    a = b = c

    is perfectly valid syntax. Only the stupid doesn't understand this line of code.

  • the beholder (unregistered) in reply to ClaudeSuck.de
    ClaudeSuck.de:
    Shinobu:
    Meanwhile, in VB you don't need := or == since it's always clear from context which is meant. You don't assign in expressions, and a comparison can never be a statement. It makes sense, is clear, you can always use =, and you never get weird bugs from accidentally using = instead of ==.

    and that's why

    a = b = c

    is perfectly valid syntax. Only the stupid doesn't understand this line of code.

    100% agreed. VB may have its flaws, but the one thing nobody shouldn't whine about is the lack of a separation between operators because context tells you what that = means.

    Writing "if (a = b){" on other languages bit me one too many times.

  • Paul Neumann (unregistered) in reply to ClaudeSuck.de
    ClaudeSuck.de:
    ... and that's why

    a = b = c

    is perfectly valid syntax. Only the stupid doesn't understand this line of code.

    This is valid in other languages as well, however the results are less surprising: c is assigned to b is assigned to a

  • caper (unregistered)

    "clear from context which is meant."

    flag = value = 7

    Multiple assignment or logical expression ? I suppose if one knows that flag is a boolean, but only in strongly typed languages.

  • Brian (unregistered)

    The correct way is SystemInformation.PowerStatus.BatteryLifePercent.ToString("0%")

    That's it. Changes a double to a whole-number percentage string.

  • (cs) in reply to frits
    frits:
    Hey this is VB, why don't they just mulitply the string by 100 and concatanate the "%" character?
    Multiply a string by 100? How can you do that? My rational mind just imploded.
  • (cs) in reply to Schmitter
    Schmitter:
    I am 100% sure there is a better way to do that.
    Oh, really?
  • (cs) in reply to Myth
    Myth:
    Mr. Blutarsky:
    What if the battery power is 0.0?

    Then how is the code going to run?

    -1 for not seeing the obvious case of the device being plugged in.

    -1000 for not seeing the Animal House reference.

  • (cs) in reply to TheRider
    TheRider:
    frits:
    Hey this is VB, why don't they just mulitply the string by 100 and concatanate the "%" character?
    Multiply a string by 100? How can you do that? My rational mind just imploded.
    Not a VB programmer, then?
  • (cs) in reply to TheRider
    TheRider:
    Multiply a string by 100? How can you do that? My rational mind just imploded.
    Because it's actually a variant rather than a string.
  • Jim (unregistered)

    Working with Objective C, you need to make sure objects haven't been deallocated:

        If SystemInformation.PowerStatus.BatteryLifePercent.ToString = "1" && 
    

    SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "100%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.99" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "99%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.98" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "98%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.97" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "97%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.96" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "96%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.95" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "95%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.94" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "94%" ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.93" && SystemInformation.PowerStatus.BatteryLifePercent.ToString != nil Then Return "93%" ...

  • Jay (unregistered)

    Oh, I get it now!! The code isn't enterprisey enough. It's not re-usable because he not only hard-codes the BatteryLifePercent function, but he also embeds the "%" in the return value, thus making it inapplicable to other cases. What he should have written was this:

    
    
    Public Function NumberToString100(number as Integer) as String
            If number.ToString = "1" Then
                Return "100"
            ElseIf number.ToString = "0.99" Then
                Return "99"
            ElseIf number.ToString = "0.98" Then
                Return "98"
            '...
            'snip
            '...
            ElseIf number.ToString = "0.03" Then
                Return "3"
            ElseIf number.ToString = "0.02" Then
                Return "2"
            ElseIf number.ToString = "0.01" Then
                Return "1"
            Else
                Return "NA"
            End If
    End Function
    Public ReadOnly Property BatteryPercent()
        ' This code will retrieve the BatteryLifePercent property and convert it to a percent.
        Get
            dim number100=NumberToString100(SystemInformation.PowerStatus.BatteryLifePercent)
            If number100 = "100" Then
                Return "100%"
            ElseIf number100 = "99" Then
                Return "99%"
            ElseIf number100 = "98" Then
                Return "98%"
            ElseIf number100 = "97" Then
                Return "97%"
            '...
            'snip
            '...
            ElseIf number100 = "3" Then
                Return "3%"
            ElseIf number100 = "2" Then
                Return "2%"
            ElseIf number100 = "1" Then
                Return "1%"
            Elseif number100 = "NA" then
                return "NA"
            else
                Return "Other NA"
            End If
        End Get
    End Property
    
  • (cs)

    C'mon.. I want to know what was snipped!

  • chf (unregistered)

    You guys laugh, roll eyes or wonder how someone could code like this. Sadly I've seen this style of copy-paste coding from quite alot of people taught in Indian universities. I'm not simply stereotyping, this is a phenomena observed by other colleagues too. It really is incredible how bad the level of instruction they receive over there. Surely it's gotten better but I wouldn't hold my breath...

Leave a comment on “The Percent Conversion”

Log In or post as a guest

Replying to comment #:

« Return to Article