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\$
19
  • 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, 2018 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\$
    – Wheat Wizard
    Jul 30, 2018 at 20:36
  • 3
    \$\begingroup\$ Why is the output format so strict? \$\endgroup\$
    – Okx
    Jul 30, 2018 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, 2018 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 R
    Jul 31, 2018 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\$
11
  • 38
    \$\begingroup\$ Takes a while (since it searches the entire filesystem) - but it saves a byte! - that's code golf for you! \$\endgroup\$ Jul 31, 2018 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\$ Jul 31, 2018 at 13:24
  • 4
    \$\begingroup\$ @EriktheOutgolfer I'm told I can assume a fresh install. \$\endgroup\$
    – Okx
    Jul 31, 2018 at 13:30
  • 11
    \$\begingroup\$ @EriktheOutgolfer I'm so glad Brunch is served before the world ends. \$\endgroup\$
    – mbomb007
    Jul 31, 2018 at 13:41
  • 1
    \$\begingroup\$ @algmyr At that point I might as well do echo {0.100} \$\endgroup\$
    – Okx
    Aug 1, 2018 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\$
9
  • \$\begingroup\$ You can save one byte by using ES6 string templates: `Remaining battery is ${b.level*100}%` \$\endgroup\$ Jul 31, 2018 at 10:59
  • \$\begingroup\$ @Benoit Esnard: Nice idea! Thanks ... \$\endgroup\$
    – Night2
    Jul 31, 2018 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\$ Jul 31, 2018 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\$ Jul 31, 2018 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, 2018 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\$
9
  • 1
    \$\begingroup\$ Using this tip, you can golf down the lengthy property name -- ((gwmi win32_battery)|% e*g). \$\endgroup\$ Jul 30, 2018 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, 2018 at 20:44
  • \$\begingroup\$ If the device has more than one battery, it displays something like Remaining battery is 98 96% \$\endgroup\$
    – Spc_555
    Jul 31, 2018 at 9:46
  • \$\begingroup\$ @VasilyAlexeev OP sounds like we may choose an appropriate device. \$\endgroup\$
    – Adám
    Jul 31, 2018 at 10:50
  • \$\begingroup\$ Change "abc"+(def)+"ghi" to "abc$(def)ghi" to save some more. \$\endgroup\$
    – colsw
    Jul 31, 2018 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\$
6
  • \$\begingroup\$ What did you test this on? Ubuntu or similar I'm guessing? It doesn't work on Mac, for example. \$\endgroup\$ Jul 31, 2018 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, 2018 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, 2018 at 13:38
  • \$\begingroup\$ @Wilf acpi simply isn't there on Mac it seems. \$\endgroup\$ Jul 31, 2018 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, 2018 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\$
2
  • 1
    \$\begingroup\$ Idk. It's included on TIO. I'll include a link to the module. \$\endgroup\$
    – mbomb007
    Jul 30, 2018 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, 2018 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\$
5
  • \$\begingroup\$ What happens if you omit the include? \$\endgroup\$
    – Ruslan
    Aug 1, 2018 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\$ Aug 1, 2018 at 11:27
  • \$\begingroup\$ Did you try compiling with /Gz (default to __stdcall)? \$\endgroup\$
    – Neil
    Aug 7, 2018 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\$ Aug 7, 2018 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, 2018 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\$
6
  • 2
    \$\begingroup\$ Not 64-bit pointer safe? What? That's ridiculous, Microsoft. \$\endgroup\$
    – user253751
    Aug 1, 2018 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\$ Aug 1, 2018 at 10:45
  • \$\begingroup\$ Can you not use a byte array instead of a structure? \$\endgroup\$
    – Neil
    Aug 7, 2018 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\$ Aug 7, 2018 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, 2018 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\$
2
  • \$\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 R
    Jul 31, 2018 at 19:50
  • \$\begingroup\$ This works for 130 bytes. \$\endgroup\$
    – ovs
    Aug 1, 2018 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\$
5
  • \$\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, 2018 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\$ Aug 2, 2018 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, 2018 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\$ Aug 3, 2018 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\$ Aug 3, 2018 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.