26
\$\begingroup\$

Display the remaining battery charge, as a percentage of maximum charge

Remember if you can't run your code on a phone, calculator, etc, you can probably install your environment on a laptop at least. If you absolutely can't run on a device that has a battery, then unfortunately your language isn't eligible since you have no useful value to print.

You must display the results on the screen. This is theoretically supposed to be a handy utility for the user to check the battery. Writing battery percent to a file is too clunky, requiring the user to then check the file. Displaying on-screen is therefore a part of the specification that can't be overridden by default IO. That said, you can assume nothing is preventing things like STDOUT from being displayed on screen in the usual way.

If the battery percent is already displayed on screen all the time by the OS, like on many phones, that does not mean you've got a zero-byte solution. You must assume that built-in display doesn't exist, and display the battery percent again somewhere else.

Edit: The output format is being opened up. You are free to display as little as just the digits of the percent, or the digits with some extra output as well.

Edit2: The digits representing the percent must appear in a known location within the output, not more than 50 lines from the end of the output, and that location shouldn't change between invocations. The digits representing the percent must be separated from other output by at least one non-digit character on each side.

For reference here is the old output format from before the change:

Remaining battery is ddd% or Remaining battery is ddd percent

\$\endgroup\$
  • 11
    \$\begingroup\$ This is a uniqueish challenge because the language chosen depends largely on the environment and the best golf is going to rely greatly on the api presented in that environment. Not sure if that's good or bad, ha \$\endgroup\$ – Poke Jul 30 '18 at 19:34
  • 4
    \$\begingroup\$ What is battery percentage defined as? I'm not really familiar with how the hardware works but I was always under the impression that battery percentage was some kind of hueristic in terms of predicted use. \$\endgroup\$ – Sriotchilism O'Zaic Jul 30 '18 at 20:36
  • 3
    \$\begingroup\$ Why is the output format so strict? \$\endgroup\$ – Okx Jul 30 '18 at 20:38
  • 1
    \$\begingroup\$ @WW I think I've heard of phones displaying that as the 'percent'. They shouldn't, of course, that's just misleading and condescending to the user. But short of asking people to golf a new hardware-level device driver, I'm willing to accept any % that the OS or system-level API gives. \$\endgroup\$ – Jared K Jul 30 '18 at 20:45
  • 2
    \$\begingroup\$ @user202729 That electronics.SE answer is about the internal measurement, but what's exposed to the user is often a doctored number - Li-ion batteries drain faster the more charge they have (or is it the other way around?), but the device (usually) adjusts for that to show a somewhat linear change in battery percentage since that feels more predictable to us users. \$\endgroup\$ – sundar Jul 31 '18 at 17:25

11 Answers 11

43
\$\begingroup\$

Bash, 70 67 50 46 43 16 bytes

`</*/*/*/B*/c*y`

Outputs: <battery 0-100>: command not found

Reads the file /sys/class/power_supply/BAT1/capacity.

Tested using Ubuntu 18.04 on a LENOVO ideapad 500.

Takes a while (since it searches the entire filesystem) - but it saves a byte!

Old answer:

echo Remaining battery is `</*/*/*/B*/c*y`%
\$\endgroup\$
  • 37
    \$\begingroup\$ Takes a while (since it searches the entire filesystem) - but it saves a byte! - that's code golf for you! \$\endgroup\$ – Stewie Griffin Jul 31 '18 at 11:17
  • 11
    \$\begingroup\$ Hm, I'm not sure if it can be guaranteed that there isn't a file called /so/apes/yadayada/Brunch/calamity. \$\endgroup\$ – Erik the Outgolfer Jul 31 '18 at 13:24
  • 3
    \$\begingroup\$ @EriktheOutgolfer I'm told I can assume a fresh install. \$\endgroup\$ – Okx Jul 31 '18 at 13:30
  • 11
    \$\begingroup\$ @EriktheOutgolfer I'm so glad Brunch is served before the world ends. \$\endgroup\$ – mbomb007 Jul 31 '18 at 13:41
  • 1
    \$\begingroup\$ @algmyr At that point I might as well do echo {0.100} \$\endgroup\$ – Okx Aug 1 '18 at 12:01
13
\$\begingroup\$

JavaScript (browser), 78 77 50 bytes

(-1 byte thanks to Benoit Esnard)

(-27 bytes since the output format is flexible now)

navigator.getBattery().then(b=>alert(b.level*100))

JavaScript (browser), 46 bytes, by returning a promise

(Suggested by Shaggy, requires a header and footer)

f=
_=>navigator.getBattery().then(b=>b.level*100)
f().then(alert)


Note: Only works on Google Chrome >= 38 (desktop and Android) or any other browser that supports Battery API. FireFox has removed this API due to privacy concerns.

Example on Android (old output format):

enter image description here

Example on a Windows laptop (old output format):

enter image description here

\$\endgroup\$
  • \$\begingroup\$ You can save one byte by using ES6 string templates: `Remaining battery is ${b.level*100}%` \$\endgroup\$ – Benoit Esnard Jul 31 '18 at 10:59
  • \$\begingroup\$ @Benoit Esnard: Nice idea! Thanks ... \$\endgroup\$ – Night2 Jul 31 '18 at 11:14
  • 2
    \$\begingroup\$ I never realised you can get a user's battery level in a webpage. I can't think of when that feature would actually be useful to a user though. \$\endgroup\$ – numbermaniac Jul 31 '18 at 12:28
  • 2
    \$\begingroup\$ @numbermaniac Back in the days, PoC featured websites that included a low-power mode based on the battery level of the device. Too bad they didn't think all of this could also be used to track you without the need of cookies. \$\endgroup\$ – Alexis Facques Jul 31 '18 at 12:39
  • 4
    \$\begingroup\$ @numbermaniac: One of the usages is to auto save a form when user's battery is low. But there can be many misuses for it and that is why FireFox has removed it. \$\endgroup\$ – Night2 Jul 31 '18 at 12:56
12
\$\begingroup\$

PowerShell, 28 bytes

-26 (!) thanks to AdmBorkBork. Previous version -3 thanks to colsw.

((gwmi win32_battery)|% e*g)

enter image description here

gwmi is short for Get-WmiObject

|% takes the pattern e*g and finds the only matching property; estimatedChargeRemaining

\$\endgroup\$
  • 1
    \$\begingroup\$ Using this tip, you can golf down the lengthy property name -- ((gwmi win32_battery)|% e*g). \$\endgroup\$ – AdmBorkBork Jul 30 '18 at 20:18
  • \$\begingroup\$ @AdmBorkBork Thank you again. As you can tell, I'm not a Powershell golfer (or even user). Just used a bit of Google-fu… \$\endgroup\$ – Adám Jul 30 '18 at 20:44
  • \$\begingroup\$ If the device has more than one battery, it displays something like Remaining battery is 98 96% \$\endgroup\$ – Vasily Alexeev Jul 31 '18 at 9:46
  • \$\begingroup\$ @VasilyAlexeev OP sounds like we may choose an appropriate device. \$\endgroup\$ – Adám Jul 31 '18 at 10:50
  • \$\begingroup\$ Change "abc"+(def)+"ghi" to "abc$(def)ghi" to save some more. \$\endgroup\$ – colsw Jul 31 '18 at 15:07
10
\$\begingroup\$

Bash+acpi, 43 4 bytes

New rules

acpi

output on form

Battery 0: Charging, 92%, 00:05:37 until charged

not sure if the rule change makes things more interesting, couldn't you dump any text that contains all strings 0 to 100 which would be valid output? Seems to lose the original intent if so.

Old rules

set `acpi`;echo Remaining battery is ${4%,}

output on form

Remaining battery is 92%

Don't ask me why set works like this, but it does.

\$\endgroup\$
  • \$\begingroup\$ What did you test this on? Ubuntu or similar I'm guessing? It doesn't work on Mac, for example. \$\endgroup\$ – numbermaniac Jul 31 '18 at 12:27
  • \$\begingroup\$ Works on fedora, but it depends heavily on the syntax of the output (what is it on mac for reference? @numbermaniac )? \$\endgroup\$ – Wilf Jul 31 '18 at 13:30
  • \$\begingroup\$ I assume it's the one available for most linux distros. Is the acpi output format different on mac perhaps (is acpi even available there)? \$\endgroup\$ – algmyr Jul 31 '18 at 13:38
  • \$\begingroup\$ @Wilf acpi simply isn't there on Mac it seems. \$\endgroup\$ – numbermaniac Jul 31 '18 at 23:28
  • \$\begingroup\$ It can to be installed separately on some linux distros, mac likely has its own built in equivalent drivers and commands. \$\endgroup\$ – Wilf Aug 1 '18 at 9:59
6
\$\begingroup\$

Python 3.6 + psutil, 80 bytes

import psutil
print(f"Remaining battery is {psutil.sensors_battery().percent}%")

Try it online!

If the machine has no battery (like on TIO), the program will throw an error, because psutil.sensors_battery() returns None.

This requires Python 3.6 for string interpolation.

\$\endgroup\$
  • 1
    \$\begingroup\$ Idk. It's included on TIO. I'll include a link to the module. \$\endgroup\$ – mbomb007 Jul 30 '18 at 21:23
  • \$\begingroup\$ I Googled and found the same library but my Python 2 answer was not as smart as yours with string interpolation. Note to self: must get into Python 3.6 and answer faster. +1 \$\endgroup\$ – ElPedro Jul 31 '18 at 18:27
5
\$\begingroup\$

C (win32, gcc i686-w64-mingw32), 78 bytes

#include<windows.h>
main(s){GetSystemPowerStatus(&s);printf("%hhu",s>>16);}

Abuses the win32 API by letting GetSystemPowerStatus() write "somewhere" on the stack, the interesting member is in the third byte, according to the SYSTEM_POWER_STATUS struct.

Unfortunately, the #include seems to be needed, probably because of calling conventions.

Example output:

> bat.exe
90

Displays 255 on systems without a battery.

\$\endgroup\$
  • \$\begingroup\$ What happens if you omit the include? \$\endgroup\$ – Ruslan Aug 1 '18 at 11:25
  • 1
    \$\begingroup\$ @Ruslan the linker doesn't find the symbol in kernel32.dll. That's why I think it's the calling convention, win32 API functions don't use the "standard" cdecl. So even if I could trick the linker somehow, the code probably wouldn't work anyways. \$\endgroup\$ – Felix Palmen Aug 1 '18 at 11:27
  • \$\begingroup\$ Did you try compiling with /Gz (default to __stdcall)? \$\endgroup\$ – Neil Aug 7 '18 at 0:24
  • \$\begingroup\$ @Neil no, does gcc/mingw have a similar option or do I have to use msvc for that? And wouldn't that break the printf() without a prototype? \$\endgroup\$ – Felix Palmen Aug 7 '18 at 6:51
  • \$\begingroup\$ Sorry, I hadn't read your header carefully enough. I think the mingw version is -mrtd, but I don't know what would happen to printf(); maybe there's a shorter include for it? \$\endgroup\$ – Neil Aug 7 '18 at 7:50
4
\$\begingroup\$

Excel VBA, 150 bytes

Restricted to 32-Bit Windows Installs of office, because the windows Kernel32 call is not 64-bit pointer safe.

Outputs to the cell A1 on the ActiveSheet.

Declare Sub GetSystemPowerStatus Lib"kernel32"(f As t)
Type t
i As Integer
b As Byte
End Type
Sub d
Dim e As t
GetSystemPowerStatus e
[A1]=e.b
End Sub

-26 bytes thanks to flexible output

-7 bytes thanks to @Neil for using an Int instead of 2 bytes

\$\endgroup\$
  • 2
    \$\begingroup\$ Not 64-bit pointer safe? What? That's ridiculous, Microsoft. \$\endgroup\$ – immibis Aug 1 '18 at 3:45
  • \$\begingroup\$ @immibis it has do do with a difference between the versions - if you are using a 64 bit install of Office then the call just changes to be Declare PtrSafe Sub GetSystemPowerStatus Lib"kernel32"(f As t) \$\endgroup\$ – Taylor Scott Aug 1 '18 at 10:45
  • \$\begingroup\$ Can you not use a byte array instead of a structure? \$\endgroup\$ – Neil Aug 7 '18 at 0:27
  • \$\begingroup\$ @Neil - unfortunately not, the Lib call assigns f to a pointer of the _SYSTEM_POWER_STATUS structure, which holds both byte and dword values, meaning that, in this case, the structure has to be emulated from within vba, and a byte array cannot be used. \$\endgroup\$ – Taylor Scott Aug 7 '18 at 11:06
  • \$\begingroup\$ If you can't use an array, can you not at least use a two-byte type as your padding instead of two single bytes? \$\endgroup\$ – Neil Aug 7 '18 at 13:08
3
\$\begingroup\$

QPython for Android, 133 bytes

from androidhelper import*
d=Android()
d.batteryStartMonitoring()
d.dialogCreateAlert(str(d.batteryGetLevel()[1])+"%")
d.dialogShow()

Code screen

Output screen

The +"%" isn't strictly necessary since it uses the newer more flexible output format anyway, but it makes for slightly nicer output at just +4 bytes.

\$\endgroup\$
  • \$\begingroup\$ [d.notify (create notification alert) would have been much shorter than creating and displaying the dialog, but for some reason it doesn't work, at least on my device (possibly, it hasn't been updated for newer Android APIs).] \$\endgroup\$ – sundar Jul 31 '18 at 19:50
  • \$\begingroup\$ This works for 130 bytes. \$\endgroup\$ – ovs Aug 1 '18 at 12:57
2
\$\begingroup\$

Emacs Lisp, 9 bytes

(battery)

Shows current battery status in mini-buffer at the bottom (or to stdout when using --batch) in format such as: Power N/A, battery Unknown (99.1% load, remaining time N/A).

Should work on Windows, OSX, BSD , and Linux.

\$\endgroup\$
1
\$\begingroup\$

Japt, 60 bytes

Ox`nàÀÓ&.getBÂjry().È(x=>O.q("Rà@°á ßMy  "+L*x.¤vel+"%"))

Test it

\$\endgroup\$
1
\$\begingroup\$

Java, 546 bytes (Windows XP or Higher)

The powercfg utility came into play for WindowsXP, I have no idea what utilities were available prior to this. I must also be run as administrator. This is god-awful and I didn't make an extreme golfing attempt...

import java.io.*;import java.util.Scanner;public class J {public static void main(String[] args)throws Exception{Process p=Runtime.getRuntime().exec("powercfg energy");p.waitFor();Scanner s=new Scanner(new File("C:\\windows\\system32\\energy-report.html"));String x;double a=0,b=0;while(s.hasNextLine()){x=s.nextLine();if(x.contains("Design Capacity")){s.nextLine();b=Integer.parseInt(s.nextLine().replaceAll("\\D+",""));}else if(x.contains("Last Full Charge")){s.nextLine();a=Integer.parseInt(s.nextLine().replaceAll("\\D+",""));}}System.out.print(a/b*100);}}

Formatted / commented...

import java.io.*;
import java.util.Scanner;

public class J {
    public static void main(String[] args) throws Exception {
        Process p = Runtime.getRuntime().exec("powercfg energy"); // Run CMD sys32 app.
        p.waitFor();                                              // Wait for it.
        Scanner s = new Scanner(new File(
                "C:\\windows\\system32\\energy-report.html"));    // Read output.
        String x;
        double a = 0, b = 0;
        while (s.hasNextLine()) {
            x = s.nextLine();
            if (x.contains("Design Capacity")) {                   // Find max capacity.
                s.nextLine();
                b = Integer.parseInt(s.nextLine().replaceAll("\\D+", ""));
            } else if (x.contains("Last Full Charge")) {           // Find current capacity.
                s.nextLine();
                a = Integer.parseInt(s.nextLine().replaceAll("\\D+", ""));
            }
        }
        System.out.print(a / b * 100); // Calculate %.
    }
}

Honestly I was more interested to see if it was even possible in Java.

\$\endgroup\$
  • \$\begingroup\$ Having to call an external command like that, then read the results of the external command from a file... then having to calculate the percentage yourself. And so verbose. It's awful I love it. I'm glad people try these things in ill-suited languages it's so fun. +1 \$\endgroup\$ – Jared K Aug 2 '18 at 17:42
  • 1
    \$\begingroup\$ @JaredK I enjoy Java "golfing", but only on questions where people think, "oh god no, what moron would ever try this in Java? It just wouldn't make sense." Sort of ironic. \$\endgroup\$ – Magic Octopus Urn Aug 2 '18 at 18:02
  • \$\begingroup\$ Sometimes I think Java ought to get a golfing version like how Japt was made for golfing Javascript. \$\endgroup\$ – Jared K Aug 3 '18 at 16:06
  • \$\begingroup\$ @JaredK look into Groovy or Clojure, could probably turn this into a 100 byte groovy answer if I tried super hard. \$\endgroup\$ – Magic Octopus Urn Aug 3 '18 at 18:40
  • \$\begingroup\$ @JaredK here's an approximation of this same answer in groovy: {Runtime.getRuntime().exec("powercfg energy").waitFor();x=new XMLSlurper(new File("C:\\windows\\system32\\energy-report.html"));x.html.table.tr[#].span[0] as int/x.html.table.tr[#].span[0] as int} \$\endgroup\$ – Magic Octopus Urn Aug 3 '18 at 18:46

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.