Gelişmiş Python Geliştirme Kursu
Bölüm
>
Seviye
Serileştirme modülleri
Yapı Modülü
Amaç
struct modülünü kullanarak yeni tarım arazisi için nihai veri ayrımını kurun.
Yolun sonunda, halihazırda inşa edilmiş yeni tarım arazisini ve ekili mahsulleri yöneten bir servis istasyonu bulunmaktadır. Burada, ekili mahsullerin verilerini inceleyip işleyeceğiz ve tarım arazisinin tahmini çıktısını alacağız. Bu bölümdeki diğer seviyelerde olduğu gibi veriyi serileştirme ve serileştirilmiş veriyi geri alma işlemleriyle çalışırken, struct adında son bir modülü tanıtacağız.
struct modülü, veriyi ikili biçimde paketleyerek serileştiren bir dizi fonksiyon tanıtır. Ancak, daha önce çalıştığımız diğer modüllerden farklı olarak, verinin serileştirildiği ve daha sonra serileştirme durumunun geri alındığı durumu kontrol etmekte daha fazla esneklik sunar; bu da onu diğer modüllerden daha çok yönlü hale getirir. Aşağıdaki fonksiyonları kullanarak veriyi işlemek için import struct kullanın:
struct.calcsize(): Belirli bir format dizgisinin kaç bayta paketleneceğini belirler. Tek (1) argüman alır: bayt boyutunu doğrulamak istediğiniz format. Kullanacağımız formatlar:- integer:
'i'ile temsil edilir; tam sayılarla temsil edilen verilerin formatıdır. - float:
'f'ile temsil edilir; ondalık sayılarla temsil edilen verilerin formatıdır. - double:
'd'ile temsil edilir; float formatının yetersiz kaldığı daha karmaşık ondalık sayılarla temsil edilen verilerin formatıdır.
- integer:
struct.pack(): Seçtiğiniz formatta veriyi ikili olarak serileştirip paketler. İki (2) veya daha fazla argüman alır; ilki kullanmak istediğiniz format, ikincisi ise serileştirmek istediğiniz değerlerdir. Kullanılan formatlar yukarıda belirtildiği gibidir ve eklediğiniz argüman sayısına karşılık gelen formatların eklenmesi gerekir.struct.unpack(): Paketlenmiş ikili veriyi geri alır; iki (2) argüman alır: serileştirildiği formatla uyumlu olması gereken format ve serileştirilen veri.struct.iter_unpack(): Paketlenmiş ikili veriyi geri alır;struct.unpack()ile aynı şekilde çalışır, ancak bir döngü aracılığıyla her veri bloğunu ayrı ayrı iterasyona sokar.struct.pack_into():struct.pack()fonksiyonunun gelişmiş bir versiyonu olup, dört (4) argüman alır: kullanmak istediğiniz format, veriyi koymak istediğiniz veri tamponu, verinin yerleştirileceği tampondaki konum ve son olarak paketlemek istediğiniz veri.struct.unpack_from():struct.unpack()fonksiyonunun gelişmiş bir versiyonu olup, üç (3) argüman alır: kullanmak istediğiniz format, paketlenmiş veriyi içeren veri tamponu ve son olarak veriyi geri almak istediğiniz tampondaki konum. Bu, verinin belirli bölümlerini geri almanıza olanak tanır.
Servis istasyonundaki ışık işaretine (X) doğru yürüyün ve masaya yönelin, ardından integer, float ve double adında üç (3) değişken oluşturun. Bunları, struct.calcsize() fonksiyonu kullanılarak her formatın bayt cinsinden boyutunu doğrulamak için kullanacağız. integer değişkeni için fonksiyonu 'i' argümanı ile, float değişkeni için 'f' argümanı ile ve son olarak double değişkeni için fonksiyonu 'd' argümanı ile kullanın. Örneğin: integer = struct.calcsize('i') . Oluşturduğunuz üç (3) değişkeni önceden yazılmış write() fonksiyonuna ekleyin.
Altın X işaretine doğru yürüyün ve yeni tarım arazisi ile ilgili verileri toplamak için read() fonksiyonunu kullanın, verilerin noktalarını ve formatlarını not alın: Resources , Size ve Estimate. Not aldıktan sonra, ışıklı X işaretine doğru yürüyüp mavi halı üzerinde blue_data adında bir değişken oluşturun.
blue_data değişkeninde, daha önce not aldığınız format ve değerleri argüman olarak belirleyerek struct.pack() fonksiyonunun değerini saklayın. Formatı yazarken, format türlerini tek bir birime "paketlemeniz" gerekir. Örneğin, tamsayı formatı daha önce belirtildiği gibi 'i' olarak etiketlenmişse, üç tamsayı veri türü ekliyorsanız bunları 'iii' olarak eklemeniz gerekir. Benzer şekilde, bir tamsayı, bir ondalık sayı ve bir double ekliyorsanız, bu 'ifd' olarak yazılır. Verileri eklerken, bunları argüman olarak ayrı ayrı yerleştirirsiniz. Genel bir örnek aşağıdaki gibidir:
data_1 = 8 # is an integer data_2 = 2.25 # is a float data_3 = 900.702938103 # is a double blue_data = struct.pack('ifd', data_1, data_2, data_3)
struct.pack() fonksiyonu, verileri nasıl formatlayacağınızı belirlemenize ve aynı anda birden fazla veri noktasını serileştirmenize olanak tanıyan büyük bir esneklik sağlar. Önceden okunan verileri, yukarıdaki örneği temel alarak ekleyin. Paketlenmiş veriyi görmek için blue_data argümanı ile display() fonksiyonunu kullanın.
Koyu X işaretine doğru yürüyün, mavi halı üzerinde terminale doğru yüzün, blue_unpack adında bir değişken oluşturun ve struct.unpack() fonksiyonunun değerini, veriyi paketlemek için kullandığınız aynı formatı ve blue_data değişkenini argüman olarak ekleyerek saklayın. Format, struct.pack() fonksiyonu ile aynı şekilde yazılır, böylece veriyi ilk serileştirdiğiniz gibi geri alabilirsiniz. Daha önce paketlediğiniz veriyi doğrulamak için write() fonksiyonu içine blue_unpack ekleyin.
Aynı konumda struct.iter_unpack() fonksiyonunu da kullanacağız; bu fonksiyon struct.unpack() ile aynı argümanları alır ancak artık for döngüsü biçiminde yazılmıştır, bu da verileri tek tek döngüye sokmamıza olanak tanır. Fonksiyon aşağıdaki gibi kodlanmıştır:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
Eksik argümanlar için, struct.iter_unpack() fonksiyonuna daha önce struct.unpack() ile kullanılan aynı argümanları ekleyin; zira bunlar aynı fonksiyonun farklı kullanımlarıdır.
Kırmızı halı üzerindeki altın X işaretine doğru yürüyün, masaya yüz çevirin ve read() fonksiyonunu kullanarak mahsul miktarlarını gözden geçirin. Her mahsulün miktarını ve formatını not alın. Kırmızı halı üzerindeki ışıklı X işaretine doğru yürüyün ve buffer adında bir nesne oluşturun, bu nesneye bytearray(16) değerini ekleyin. Bu, veriyi elle yerleştirilebileceğiniz bir veri bankası gibi çalışan byte'lardan oluşan bir koleksiyondur. Argüman olarak kullanılan 16 sayısı, buffer nesnesinde kaç bayt saklanabileceğini belirtir.
Oluşturduğunuz buffer nesnesini doldurmak için struct.pack_into() fonksiyonunu kullanın. Fonksiyonun değerini saklamak için bir değişken oluşturmanıza gerek yoktur, çünkü fonksiyonun kendisi değerleri doğrudan buffer nesnesine yerleştirecektir. Daha önce not aldığınız her bir değer için bu fonksiyonu ve özgün argümanlarını kullanarak doldurun.
Örneğin, verilen ilk mahsul değeri için format, bayt pozisyonu ve miktarı size sağlanacaktır. İlk argüman olarak formatı, ikinci argüman olarak veriyi serileştirmek istediğiniz yeri (bu durumda buffer), üçüncü argüman olarak buffer içindeki değeri eklemek istediğiniz pozisyonu belirleyin; format, kullanılacak bayt sayısını belirlediği için, daha önce kullanılmamış bir alanı doldurmanıza dikkat edin. Son olarak, serileştirmek ve buffer nesnesine paketlemek istediğiniz değeri ekleyin.
struct.pack_into('i', buffer, 0, 82)
Önceden belirtildiği gibi buffer nesnesinde 16 bayt bulunur. Yukarıdaki kodda, tamsayı formatı 4 bayt olup pozisyon 0'da yerleştirilmiştir. Bu, veriyi buffer içerisine yerleştirdikten sonra, buffer içinde sadece 12 baytın boş kalacağı anlamına gelir; pozisyon 0-3 arası verilen değer olan 82 ile doldurulmuştur. Daha önce okunan ve not alınan tüm mahsul veri noktaları için bunu yapın, toplamda üç (3) adet vardır. Paketlenmiş veriyi görüntülemek için display() fonksiyonunu kullanın ve argüman olarak buffer ekleyin.
Kırmızı halı üzerindeki koyu X işaretine doğru yürüyün ve terminale yüz çevirin; burada, verinin içeriklerini doğrulamak için veriyi geri alacağız. Her bir veri noktasını ayrı ayrı geri almak için lettuce, carrots ve melons adında üç değişken oluşturun. Her değişken için, daha önce verileri paketlemek için kullandığınız aynı verilerle struct.unpack_from() fonksiyonunun değerini saklayın. İlk argüman olarak formatı, ikinci argüman olarak buffer nesnesini, üçüncü argüman olarak ise buffer içinden hangi konumdan geri almak istediğinizi belirtin. Örneğin:
lettuce = struct.unpack_from('i', buffer, 0)
Bu veri, daha önce paketleme örneğinde verilen verinin geri alınmış haline karşılık gelmektedir; diğer iki değişken için de bunu tekrarlayın ve tamamlamak için önceden yazılmış write() fonksiyonuna lettuce, carrots ve melons değişkenlerini ekleyin.