ওয়েবে বিভিন্ন স্নিপেট রয়েছে যা আপনাকে বাইট আকার থেকে মানব পাঠযোগ্য আকার ফেরত দেওয়ার জন্য একটি ফাংশন দেয়:
>>> human_readable(2048)
'2 kilobytes'
>>>
তবে এখানে কি পাইথন লাইব্রেরি রয়েছে?
ওয়েবে বিভিন্ন স্নিপেট রয়েছে যা আপনাকে বাইট আকার থেকে মানব পাঠযোগ্য আকার ফেরত দেওয়ার জন্য একটি ফাংশন দেয়:
>>> human_readable(2048)
'2 kilobytes'
>>>
তবে এখানে কি পাইথন লাইব্রেরি রয়েছে?
উত্তর:
উপরের "খুব সহজে একটি লাইব্রেরির প্রয়োজন টাস্ক" বিষয়টিকে সরল বাস্তবায়নের মাধ্যমে সম্বোধন করা:
def sizeof_fmt(num, suffix='B'):
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
সমর্থন করে:
উদাহরণ:
>>> sizeof_fmt(168963795964)
'157.4GiB'
ফ্রেড Cirera দ্বারা
B
(অর্থাত্ বাইট ব্যতীত অন্য ইউনিটগুলির জন্য) আপনি কি চান যে ফ্যাক্টরটি 1000.0
সংখ্যাটির চেয়ে বেশি হওয়া উচিত 1024.0
?
1
4 এবং 6 এর লাইনে আপনি যে কোনও নির্ভুলতা চান তা পরিবর্তন করুন ।
একটি লাইব্রেরিতে এমন সমস্ত কার্যকারিতা রয়েছে যা দেখে মনে হয় আপনি খুঁজছেন humanize
। humanize.naturalsize()
আপনি যা খুঁজছেন তা সবই করা মনে হচ্ছে।
humanize.naturalsize(2048) # => '2.0 kB'
,humanize.naturalsize(2048, binary=True) # => '2.0 KiB'
humanize.naturalsize(2048, gnu=True) # => '2.0K'
এখানে আমার সংস্করণ। এটি কোনও ফোর-লুপ ব্যবহার করে না। এটি অবিচ্ছিন্ন জটিলতা রয়েছে, হে ( 1 ), এবং তাত্ত্বিকভাবে এখানে উত্তরগুলির চেয়ে বেশি দক্ষ যা একটি লুপ ব্যবহার করে।
from math import log
unit_list = zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2])
def sizeof_fmt(num):
"""Human friendly file size"""
if num > 1:
exponent = min(int(log(num, 1024)), len(unit_list) - 1)
quotient = float(num) / 1024**exponent
unit, num_decimals = unit_list[exponent]
format_string = '{:.%sf} {}' % (num_decimals)
return format_string.format(quotient, unit)
if num == 0:
return '0 bytes'
if num == 1:
return '1 byte'
কী চলছে তা আরও পরিষ্কার করার জন্য, আমরা স্ট্রিং ফর্ম্যাটিংয়ের কোডটি বাদ দিতে পারি। এখানে লাইনগুলি আসলে কাজটি করে:
exponent = int(log(num, 1024))
quotient = num / 1024**exponent
unit_list[exponent]
1000
হবে 1,000 bytes
।
unit_list = list(zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2]))
পাইথন 3..6+ এ নিম্নলিখিত কাজগুলি হল, আমার মতে উত্তরটি এখানে বোঝা সহজ, এবং আপনাকে ব্যবহৃত দশমিক জায়গাগুলির পরিমাণ কাস্টমাইজ করতে দেয়।
def human_readable_size(size, decimal_places=3):
for unit in ['B','KiB','MiB','GiB','TiB']:
if size < 1024.0:
break
size /= 1024.0
return f"{size:.{decimal_places}f}{unit}"
যদিও আমি জানি যে এই প্রশ্নটি প্রাচীন, আমি সম্প্রতি এমন একটি সংস্করণ নিয়ে এসেছি যা লুপগুলি এড়িয়ে চলে, log2
যেটি আকারের আদেশটি শিফট হিসাবে দ্বিগুণ হয় এবং প্রত্যয় তালিকায় একটি সূচক হিসাবে নির্ধারণ করে:
from math import log2
_suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
def file_size(size):
# determine binary order in steps of size 10
# (coerce to int, // still returns a float)
order = int(log2(size) / 10) if size else 0
# format file size
# (.4g results in rounded numbers for exact matches and max 3 decimals,
# should never resort to exponent values)
return '{:.4g} {}'.format(size / (1 << (order * 10)), _suffixes[order])
এর পাঠযোগ্যতার জন্য অযৌক্তিক হিসাবে ভাল বিবেচনা করা যেতে পারে, যদিও :)
size
বা (1 << (order * 10)
মধ্যে float()
গত লাইন (পাইথন 2 জন্য) হবে।
import math
এখানে প্রয়োজন হতে পারে ।
সবসময় তাদের মধ্যে একজন হতে হবে। আচ্ছা আজ এটা আমি। এখানে একটি ওয়ান-লাইনারের সমাধান - বা দুটি লাইন যদি আপনি ফাংশনের স্বাক্ষরটি গণনা করেন।
def human_size(bytes, units=[' bytes','KB','MB','GB','TB', 'PB', 'EB']):
""" Returns a human readable string reprentation of bytes"""
return str(bytes) + units[0] if bytes < 1024 else human_size(bytes>>10, units[1:])
>>> human_size(123)
123 bytes
>>> human_size(123456789)
117GB
units=None
পরিবর্তে ব্যবহার করে)
আপনি যদি জ্যাঙ্গো ইনস্টলড ব্যবহার করছেন তবে আপনি ফাইলসাইফর্ম্যাটও চেষ্টা করতে পারেন :
from django.template.defaultfilters import filesizeformat
filesizeformat(1073741824)
=>
"1.0 GB"
এই জাতীয় একটি গ্রন্থাগার হুইল.ফাইলসাইজ ।
>>> from hurry.filesize import alternative
>>> size(1, system=alternative)
'1 byte'
>>> size(10, system=alternative)
'10 bytes'
>>> size(1024, system=alternative)
'1 KB'
1000 বা কিবিবাইটের শক্তি ব্যবহার করা আরও প্রমিত-বান্ধব হবে:
def sizeof_fmt(num, use_kibibyte=True):
base, suffix = [(1000.,'B'),(1024.,'iB')][use_kibibyte]
for x in ['B'] + map(lambda x: x+suffix, list('kMGTP')):
if -base < num < base:
return "%3.1f %s" % (num, x)
num /= base
return "%3.1f %s" % (num, x)
পিএস কখনও এমন লাইব্রেরিতে বিশ্বাস করবেন না যা হাজার হাজার কে (বড় হাতের) প্রত্যয় দিয়ে মুদ্রণ করে :)
P.S. Never trust a library that prints thousands with the K (uppercase) suffix :)
কেন না? কোডটি নিখুঁতভাবে সাবলীল হতে পারে এবং লেখক কিলো কেসিংয়ের বিষয়টি বিবেচনা করেননি। আপনার নিয়মের উপর ভিত্তি করে যে কোনও কোড স্বয়ংক্রিয়ভাবে বরখাস্ত করা বেশ সুন্দর বলে মনে হচ্ছে ...
এটি প্রায় কোনও পরিস্থিতিতে আপনার যা প্রয়োজন প্রয়োজন তা করবে, alচ্ছিক যুক্তিগুলির সাথে স্বনির্ধারিত, এবং আপনি দেখতে পাচ্ছেন, বেশ স্ব-ডকুমেন্টিং:
from math import log
def pretty_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
pow,n=min(int(log(max(n*b**pow,1),b)),len(pre)-1),n*b**pow
return "%%.%if %%s%%s"%abs(pow%(-pow-1))%(n/b**float(pow),pre[pow],u)
উদাহরণ আউটপুট:
>>> pretty_size(42)
'42 B'
>>> pretty_size(2015)
'2.0 KiB'
>>> pretty_size(987654321)
'941.9 MiB'
>>> pretty_size(9876543210)
'9.2 GiB'
>>> pretty_size(0.5,pow=1)
'512 B'
>>> pretty_size(0)
'0 B'
উন্নত কাস্টমাইজেশন:
>>> pretty_size(987654321,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'987.7 megabytes'
>>> pretty_size(9876543210,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'9.9 gigabytes'
এই কোডটি পাইথন 2 এবং পাইথন 3 উভয়ই সামঞ্জস্যপূর্ণ। পিইপি 8 কমপ্লায়েন্স পাঠকের জন্য অনুশীলন। মনে রাখবেন, এটি আউটপুটটি বেশ সুন্দর।
হালনাগাদ:
যদি আপনার হাজার হাজার কমা প্রয়োজন হয় তবে কেবল সুস্পষ্ট এক্সটেনশনটি প্রয়োগ করুন:
def prettier_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
r,f=min(int(log(max(n*b**pow,1),b)),len(pre)-1),'{:,.%if} %s%s'
return (f%(abs(r%(-r-1)),pre[r],u)).format(n*b**pow/b**float(r))
উদাহরণ স্বরূপ:
>>> pretty_units(987654321098765432109876543210)
'816,968.5 YiB'
আপনার "হিউম্যানাইজ" ব্যবহার করা উচিত।
>>> humanize.naturalsize(1000000)
'1.0 MB'
>>> humanize.naturalsize(1000000, binary=True)
'976.6 KiB'
>>> humanize.naturalsize(1000000, gnu=True)
'976.6K'
রেফারেন্স:
তাড়াতাড়ি.ফাইলসাইজ () এর বিকল্প হিসাবে সরবরাহ করা স্নিপেটে রিফিং, এখানে একটি স্নিপেট রয়েছে যা ব্যবহৃত উপসর্গের উপর ভিত্তি করে বিবিধ নির্ভুলতা সংখ্যা দেয়। এটি কিছু স্নিপেটের মতো নিখরচায় নয়, তবে ফলাফলগুলি পছন্দ করি।
def human_size(size_bytes):
"""
format a size in bytes into a 'human' file size, e.g. bytes, KB, MB, GB, TB, PB
Note that bytes/KB will be reported in whole numbers but MB and above will have greater precision
e.g. 1 byte, 43 bytes, 443 KB, 4.3 MB, 4.43 GB, etc
"""
if size_bytes == 1:
# because I really hate unnecessary plurals
return "1 byte"
suffixes_table = [('bytes',0),('KB',0),('MB',1),('GB',2),('TB',2), ('PB',2)]
num = float(size_bytes)
for suffix, precision in suffixes_table:
if num < 1024.0:
break
num /= 1024.0
if precision == 0:
formatted_size = "%d" % num
else:
formatted_size = str(round(num, ndigits=precision))
return "%s %s" % (formatted_size, suffix)
HumanFriendly প্রকল্প যা এই সঙ্গে ।
import humanfriendly
humanfriendly.format_size(1024)
উপরের কোডটি উত্তর হিসাবে 1KB দেবে।
উদাহরণ এখানে পাওয়া যাবে ।
পূর্ববর্তী সমস্ত উত্তর থেকে অঙ্কন, এটি আমার গ্রহণ করা হয়। এটি এমন একটি বস্তু যা ফাইলের আকারকে বাইটে পূর্ণসংখ্যা হিসাবে সংরক্ষণ করবে। আপনি যখন বস্তুটি মুদ্রণের চেষ্টা করবেন তখন আপনি স্বয়ংক্রিয়ভাবে একটি মানব পাঠযোগ্য সংস্করণ পাবেন।
class Filesize(object):
"""
Container for a size in bytes with a human readable representation
Use it like this::
>>> size = Filesize(123123123)
>>> print size
'117.4 MB'
"""
chunk = 1024
units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']
precisions = [0, 0, 1, 2, 2, 2]
def __init__(self, size):
self.size = size
def __int__(self):
return self.size
def __str__(self):
if self.size == 0: return '0 bytes'
from math import log
unit = self.units[min(int(log(self.size, self.chunk)), len(self.units) - 1)]
return self.format(unit)
def format(self, unit):
if unit not in self.units: raise Exception("Not a valid file size unit: %s" % unit)
if self.size == 1 and unit == 'bytes': return '1 byte'
exponent = self.units.index(unit)
quotient = float(self.size) / self.chunk**exponent
precision = self.precisions[exponent]
format_string = '{:.%sf} {}' % (precision)
return format_string.format(quotient, unit)
আমি প্রেরকের দশমিক সংস্করণের স্থির যথাযথতা পছন্দ করি , সুতরাং উপরের জক্তির উত্তরের সাথে এর এক ধরণের সংকর সংকেত দেওয়া আছে (আপনি কি জানেন যে আপনি অ-পূর্ণসংখ্যার বেসগুলির সাথে লগ নিতে পারেন?):
from math import log
def human_readable_bytes(x):
# hybrid of https://stackoverflow.com/a/10171475/2595465
# with https://stackoverflow.com/a/5414105/2595465
if x == 0: return '0'
magnitude = int(log(abs(x),10.24))
if magnitude > 16:
format_str = '%iP'
denominator_mag = 15
else:
float_fmt = '%2.1f' if magnitude % 3 == 1 else '%1.2f'
illion = (magnitude + 1) // 3
format_str = float_fmt + ['', 'K', 'M', 'G', 'T', 'P'][illion]
return (format_str % (x * 1.0 / (1024 ** illion))).lstrip('0')
DiveIntoPython3 এই ফাংশন সম্পর্কেও কথা বলে।
আধুনিক জাঙ্গোতে স্ব-টেম্পলেট ট্যাগ রয়েছে filesizeformat
:
human-readable
ফাইলের আকারের মতো মান (যেমন '13 কেবি ',' 4.1 এমবি ',' 102 বাইট 'ইত্যাদি) ফর্ম্যাট করে ।
উদাহরণ স্বরূপ:
{{ value|filesizeformat }}
মান 123456789 হয়, আউটপুট 117.7 মেগাবাইট হবে।
আরও তথ্য: https://docs.djangoproject.com/en/1.10/ref/templates/builtins/#filesizeformat
সাধারণ 2 লাইনার সম্পর্কে কীভাবে:
def humanizeFileSize(filesize):
p = int(math.floor(math.log(filesize, 2)/10))
return "%.3f%s" % (filesize/math.pow(1024,p), ['B','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])
এটি হুডের নীচে কীভাবে কাজ করে তা এখানে:
Kb
, সুতরাং উত্তরটি X কিবি হওয়া উচিত)file_size/value_of_closest_unit
ইউনিট সহ ফিরে আসে ।ফাইলাইজ 0 বা negativeণাত্মক হলে তবে এটি কাজ করে না (কারণ লগ 0 এবং -তে সংখ্যার জন্য সংজ্ঞায়িত)। আপনি তাদের জন্য অতিরিক্ত চেক যোগ করতে পারেন:
def humanizeFileSize(filesize):
filesize = abs(filesize)
if (filesize==0):
return "0 Bytes"
p = int(math.floor(math.log(filesize, 2)/10))
return "%0.2f %s" % (filesize/math.pow(1024,p), ['Bytes','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])
উদাহরণ:
>>> humanizeFileSize(538244835492574234)
'478.06 PiB'
>>> humanizeFileSize(-924372537)
'881.55 MiB'
>>> humanizeFileSize(0)
'0 Bytes'
দ্রষ্টব্য - কেবি এবং কিবি-র মধ্যে পার্থক্য রয়েছে। কেবি এর অর্থ 1000 বাইট, যেখানে কিবি এর অর্থ 1024 বাইট। কেবি, এমবি, জিবি সবই 1000 এর গুণক, যেখানে কিবি, এমআইবি, জিআইবি ইত্যাদি সমস্ত 1024 এর গুণক it এটি সম্পর্কে আরও এখানে
def human_readable_data_quantity(quantity, multiple=1024):
if quantity == 0:
quantity = +0
SUFFIXES = ["B"] + [i + {1000: "B", 1024: "iB"}[multiple] for i in "KMGTPEZY"]
for suffix in SUFFIXES:
if quantity < multiple or suffix == SUFFIXES[-1]:
if suffix == SUFFIXES[0]:
return "%d%s" % (quantity, suffix)
else:
return "%.1f%s" % (quantity, suffix)
else:
quantity /= multiple
আপনি নীচে যেটি সন্ধান করতে চলেছেন তা ইতিমধ্যে পোস্ট করা ব্যক্তিদের মধ্যে সবচেয়ে পারফরম্যান্স বা সংক্ষিপ্ত সমাধান নয়। পরিবর্তে, এটি একটি নির্দিষ্ট ইস্যুতে কেন্দ্রীভূত করে যা অন্যান্য উত্তরগুলির মধ্যে অনেকগুলি মিস হয়।
যথা যখন ইনপুট লাইক 999_995
দেওয়া হয় তখন:
Python 3.6.1 ...
...
>>> value = 999_995
>>> base = 1000
>>> math.log(value, base)
1.999999276174054
যা নিকটতম পূর্ণসংখ্যার সাথে কাটা হয় এবং ইনপুট দেয় তা প্রয়োগ করে
>>> order = int(math.log(value, base))
>>> value/base**order
999.995
আমাদের আউটপুট নির্ভুলতা নিয়ন্ত্রণের প্রয়োজন না হওয়া পর্যন্ত এটি ঠিক আমরা প্রত্যাশা করছিলাম বলে মনে হচ্ছে । জিনিসগুলি যখন কিছুটা জটিল হয়ে উঠতে শুরু করে তখনই এটি হয়।
যথাযথতা 2 টি সংখ্যায় সেট করা সহ আমরা পাই:
>>> round(value/base**order, 2)
1000 # K
পরিবর্তে 1M
।
কীভাবে আমরা এর মোকাবিলা করতে পারি?
অবশ্যই, আমরা এটি স্পষ্টভাবে পরীক্ষা করতে পারি:
if round(value/base**order, 2) == base:
order += 1
তবে আমরা কি আরও ভাল করতে পারি? আমরা জানতে কোন পথে পেতে পারি order
আগে আমরা চূড়ান্ত পদক্ষেপ না কাটা করা উচিত?
এটি আমরা করতে পারি।
0.5 দশমিক দশমিক বৃত্তাকার নিয়ম ধরে নেওয়া, উপরের if
শর্তটি এতে অনুবাদ করে:
ফলস্বরূপ
def abbreviate(value, base=1000, precision=2, suffixes=None):
if suffixes is None:
suffixes = ['', 'K', 'M', 'B', 'T']
if value == 0:
return f'{0}{suffixes[0]}'
order_max = len(suffixes) - 1
order = log(abs(value), base)
order_corr = order - int(order) >= log(base - 0.5/10**precision, base)
order = min(int(order) + order_corr, order_max)
factored = round(value/base**order, precision)
return f'{factored:,g}{suffixes[order]}'
দান
>>> abbreviate(999_994)
'999.99K'
>>> abbreviate(999_995)
'1M'
>>> abbreviate(999_995, precision=3)
'999.995K'
>>> abbreviate(2042, base=1024)
'1.99K'
>>> abbreviate(2043, base=1024)
'2K'
Sridhar Ratnakumar
এর উত্তর উল্লেখ করুন , এতে আপডেট হয়েছে:
def formatSize(sizeInBytes, decimalNum=1, isUnitWithI=False, sizeUnitSeperator=""):
"""format size to human readable string"""
# https://en.wikipedia.org/wiki/Binary_prefix#Specific_units_of_IEC_60027-2_A.2_and_ISO.2FIEC_80000
# K=kilo, M=mega, G=giga, T=tera, P=peta, E=exa, Z=zetta, Y=yotta
sizeUnitList = ['','K','M','G','T','P','E','Z']
largestUnit = 'Y'
if isUnitWithI:
sizeUnitListWithI = []
for curIdx, eachUnit in enumerate(sizeUnitList):
unitWithI = eachUnit
if curIdx >= 1:
unitWithI += 'i'
sizeUnitListWithI.append(unitWithI)
# sizeUnitListWithI = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
sizeUnitList = sizeUnitListWithI
largestUnit += 'i'
suffix = "B"
decimalFormat = "." + str(decimalNum) + "f" # ".1f"
finalFormat = "%" + decimalFormat + sizeUnitSeperator + "%s%s" # "%.1f%s%s"
sizeNum = sizeInBytes
for sizeUnit in sizeUnitList:
if abs(sizeNum) < 1024.0:
return finalFormat % (sizeNum, sizeUnit, suffix)
sizeNum /= 1024.0
return finalFormat % (sizeNum, largestUnit, suffix)
এবং উদাহরণ আউটপুট হয়:
def testKb():
kbSize = 3746
kbStr = formatSize(kbSize)
print("%s -> %s" % (kbSize, kbStr))
def testI():
iSize = 87533
iStr = formatSize(iSize, isUnitWithI=True)
print("%s -> %s" % (iSize, iStr))
def testSeparator():
seperatorSize = 98654
seperatorStr = formatSize(seperatorSize, sizeUnitSeperator=" ")
print("%s -> %s" % (seperatorSize, seperatorStr))
def testBytes():
bytesSize = 352
bytesStr = formatSize(bytesSize)
print("%s -> %s" % (bytesSize, bytesStr))
def testMb():
mbSize = 76383285
mbStr = formatSize(mbSize, decimalNum=2)
print("%s -> %s" % (mbSize, mbStr))
def testTb():
tbSize = 763832854988542
tbStr = formatSize(tbSize, decimalNum=2)
print("%s -> %s" % (tbSize, tbStr))
def testPb():
pbSize = 763832854988542665
pbStr = formatSize(pbSize, decimalNum=4)
print("%s -> %s" % (pbSize, pbStr))
def demoFormatSize():
testKb()
testI()
testSeparator()
testBytes()
testMb()
testTb()
testPb()
# 3746 -> 3.7KB
# 87533 -> 85.5KiB
# 98654 -> 96.3 KB
# 352 -> 352.0B
# 76383285 -> 72.84MB
# 763832854988542 -> 694.70TB
# 763832854988542665 -> 678.4199PB
আপনার মন কীভাবে কাজ করে তার উপর নির্ভর করে এই সমাধানটি আপনার কাছে আবেদনও করতে পারে:
from pathlib import Path
def get_size(path = Path('.')):
""" Gets file size, or total directory size """
if path.is_file():
size = path.stat().st_size
elif path.is_dir():
size = sum(file.stat().st_size for file in path.glob('*.*'))
return size
def format_size(path, unit="MB"):
""" Converts integers to common size units used in computing """
bit_shift = {"B": 0,
"kb": 7,
"KB": 10,
"mb": 17,
"MB": 20,
"gb": 27,
"GB": 30,
"TB": 40,}
return "{:,.0f}".format(get_size(path) / float(1 << bit_shift[unit])) + " " + unit
# Tests and test results
>>> get_size("d:\\media\\bags of fun.avi")
'38 MB'
>>> get_size("d:\\media\\bags of fun.avi","KB")
'38,763 KB'
>>> get_size("d:\\media\\bags of fun.avi","kb")
'310,104 kb'