舍入系统 RAM 和 HDD 字节,向上到最接近的千兆字节。 Python

Round system RAM and HDD bytes, UP to nearest even gigabyte. Python

我正在收集当前机器的系统信息。此信息的一部分是 RAM 和 HDD 容量。问题是收集的容量是以字节而不是 GB 为单位测量的。

简而言之,如何将内部规格的显示转换为类似于您从 consumer/commercial 的角度所看到的?

1000GB HDD 或 8GB RAM,而不是可用的确切字节数。特别是由于制造商预留了不同数量的恢复扇区,RAM 可用于集成显卡和 1000 与 1024 二进制差异等...这是我当前代码的示例:

import os
import wmi #import native powershell functionality
import math

c = wmi.WMI()  
SYSINFO = c.Win32_ComputerSystem()[0]    # Manufacturer/Model/Spec blob

RAMTOTAL = int(SYSINFO.TotalPhysicalMemory)        # Gathers only the RAM capacity in bytes.
RAMROUNDED = math.ceil(RAMTOTAL / 2000000000.) * 2.000000000        # attempts to round bytes to nearest, even, GB.
HDDTOTAL = int(HDDINFO.size) # Gathers only the HDD capacity in bytes.
HDDROUNDED = math.ceil(HDDTOTAL / 2000000000.) * 2.000000000        # attempts to round bytes to nearest, even, GB.
HDDPRNT = "HDD: " + str(HDDROUNDED) + "GB"
RAMPRNT = "RAM: " + str(RAMROUNDED) + "GB"
print(HDDPRNT)
print(RAMPRNT)


感兴趣的区域是线 8-11 我将 向上 舍入到最接近的 even 数字,因为 RAM/HDD 的内部大小总是低于前面提到的原因。 Whosebug 的帖子让我得到了这个方法,它是最准确的,适用于大多数机器,但它仍然是硬编码的。这意味着 HDD 只能精确舍入数百 GB 或数千 GB,而不是两者。此外,RAM 并非 100% 准确。

这是我想到的一些解决方法,可以产生我正在寻找的结果:

PowerShell 内置了许多非常强大的本机数学功能,允许我们执行除以 1GB 之类的操作以获得特定驱动器的以千兆字节为单位的整数。

因此,要查看总物理内存四舍五入 1 GB,方法如下:

get-wmiobject -Class Win32_ComputerSystem | 
select @{Name='Ram(GB)';Expression={[int]($_.TotalPhysicalMemory /1GB)}}

此方法称为计算 属性,它与使用常规 select 语句(如 Select TotalPhysicalMemory)的不同之处在于我告诉 PowerShell 进行new Prop 调用 Ram(GB) 并使用以下表达式确定它的值。

[int]($_.TotalPhysicalMemory /1GB)

我使用的表达式从括号开始,我在此处获取 TotalPhysicalMemory(returns 为 17080483840)。然后我除以 1GB 得到 15.9074401855469。最后,我应用 [int] 将整个事物转换为整数,也就是说,使其成为整数,并适当舍入。

这是输出

>Ram(GB)
-------
 16

我想你可以写一个简单的函数来解决它。如果 kB 中的数字明显更小或更大,我添加了不同后缀的可能性(它的灵感来自一本书 Dive Into Python 3 中非常相似的示例)。它可能看起来像这样:

def round(x):
    a = 0
    while x > 1000:
        suffixes = ('kB','MB','GB','TB')
        a += 1 #This will go up the suffixes tuple with each division
        x = x /1000
    return math.ceil(x), suffixes[a]

此函数的结果可能如下所示:

>>> print(round(19276246))
(20, 'GB')
>>> print(round(135565666656))
(136, 'TB')
>>> print(round(1355))
(2, 'MB')

您可以像这样在您的代码中实现它:

import os
import wmi #import native powershell functionality
import math

def round(x):
    a = 0
    while x > 1000:
        suffixes = ('kB','MB','GB','TB')
        a += 1 #This will go up the suffixes tuple for each division
        x = x /1000
    return math.ceil(x), suffixes[a]

    .
    .
    .

RAMROUNDED = round(RAMTOTAL)       #attempts to round bytes to nearest, even, GB.
HDDTOTAL = int(HDDINFO.size) # Gathers only the HDD capacity in bytes.
HDDROUNDED = round(HDDTOTAL)        #attempts to round bytes to nearest, even, GB.
HDDPRNT = "HDD: " + str(HDDROUNDED[0]) + HDDROUNDED[1]
RAMPRNT = "RAM: " + str(RAMROUNDED[0]) + RAMROUNDED[1]
print(HDDPRNT)
print(RAMPRNT)

我结合了前面两个建议。

我使用了 if 循环而不是 while 循环,但得到了相同的结果。我还镜像了建议的 powershell 命令的相同内部过程,以使脚本更符合 python 而无需添加 modules/dependencies.

GBasMB = int(1000000000) # Allows for accurate Bytes to GB conversion

global RAMSTRROUNDED
RAMTOTAL = int(SYSINFO.TotalPhysicalMemory) / (GBasMB) # Outputs GB by dividing by previous MB variable
RAMROUNDED = math.ceil(RAMTOTAL / 2.) * 2 # Rounds up to nearest even whole number
RAMSTRROUNDED = int(RAMROUNDED) # final converted variable

HDDTOTAL = int(HDDINFO.size) / (GBasMB) # Similar process as before for HardDrive
HDDROUNDED = math.ceil(HDDTOTAL / 2.) * 2 # round up to nearest even whole number

def ROUNDHDDTBORGB(): # function for determining TB or GB sized HDD
    global HDDTBORGBOUTPUT
    global HDDPRNT
    if HDDROUNDED >= 1000: # if equal to or greater than 1000GB, list as 1TB
        HDDTBORGB = HDDROUNDED * .001
        HDDTBORGBOUTPUT = str(HDDTBORGB) + "TB"
        HDDPRNT = "HDD: " + str(HDDTBORGBOUTPUT)
        print(HDDPRNT)
    elif HDDROUNDED < 1000: # if less than 1000GB list as GB
        HDDTBORGBOUTPUT = str(str(HDDROUNDED) + "GB")
        HDDPRNT = "HDD: " + str(HDDTBORGBOUTPUT)

我已经在几十台计算机上 运行 这个脚本并且似乎准确地收集了适当数量的 RAM 和 HDD 容量。无论集成显卡决定消耗多少 RAM and/or HDD 上的保留扇区等...