Untitled
unknown
python
2 years ago
16 kB
9
Indexable
import matplotlib.pyplot as plt
def get_type(a_str):
# -- DIBUKA KE PESERTA --
# Fungsi ini akan mengembalikan tipe dari literal
# string a_str.
# get_type("0.5") -> "float"
# get_type("5.") -> "float"
# get_type("5") -> "int"
# get_type("5.a") -> "str"
# parameter:
# a_str (string): string literal dari sebuah nilai
# return (string): "int", "float", atau "str"
try:
int(a_str)
return "int"
except:
try:
float(a_str)
return "float"
except:
return "str"
def read_csv(file_name, delimiter=","):
# Dataframe adalah sebuah abstraksi tabel data siap
# proses yang dalam tugas kali ini direpresentasikan
# sebagai 3-tuple:
# (data, list nama kolom, list tipe data)
# 'data' merupakan list of lists yang menyimpan
# nilai-nilai pada tabel dan mempunyai format:
# [[row_11, row_12, ..., row_1n],
# [row_21, row_22, ..., row_2n],
# ...
# [row_m1, row_m2, ..., row_mn]]
# Satu cell row_mn dapat bertipe string, integer,
# atau float. Jika semua cell pada kolom n berisi
# literal integer, maka ubah semuanya dalam tipe
# data integer; jika bukan integer, maka ada dua kemungkinan,
# yaitu float atau string; jika semua nilai pada
# kolom n berupa number dan ada satu yang float, maka
# jadikan semua tipe data pada kolom n tersebut sebagai
# float; jika cell-cell pada kolom n ada yang tidak
# bisa dikonversikan ke integer maupun float, maka
# tipe kolom n tersebut adalah string.
# Selain list of lists yang berisi tabel, informasi
# nama kolom juga disimpan dalam bentuk
# 'list nama kolom':
# [nama_kolom_1, nama_kolom_2, ..., nama_kolom_n]
# Elemen ketiga pada 3-tuple adalah 'list tipe data'
# pada setiap kolom. Ada tiga jenis tipe data dalam
# tugas kali ini = "str", "int", dan "float". Sebuah
# kolom bertipe "int" jika semua elemen pada kolom
# tersebut adalah literal integer; "float" jika semua
# elemen pada kolom adalah literal float (dan bukan
# literal integer); "str" jika selain kedua di atas.
# Fungsi ini bertugas untuk membaca sebuah file comma
# separated value, melakukan parsing, dan mengembalikan
# dataframe yang berupa 3-tuple.
# ASUMSI file csv:
# 1. selalu ada header (nama kolom) pada baris pertama
# 2. nama kolom yang diberikan sudah dijamin unik
# Daftar Exceptions:
# 1. jika ada baris dengan jumlah kolom berbeda dari
# sebelumnya,
# raise Exception(f"Banyaknya kolom pada baris {x} tidak
# konsisten.")
# dengan x adalah nomor baris (1-based) yang kolomnya
# berlebih pertama kali.
# 2. jika tabel kosong,
# raise Exception("Tabel tidak boleh kosong.")
# parameter:
# file_name (string): nama file comma separated value
# delimiter (string): karakter pemisah antar kolom pada
# suatu baris.
# return (list, list, list): (data, list nama kolom, list tipe data)
# TODO: Implement
# open file
with open(file_name) as f:
data = f.readlines()
# error handling
if data == []:
raise Exception("Tabel tidak boleh kosong.")
# list return
database = []
jumlah_kolom = len(data[0].split(delimiter))
for i in data[1:]:
database.append(i.rstrip("\n").split(delimiter))
# memasukan header
header=data[0].rstrip("\n").split(delimiter)
# memasukan tipe
tipe = data[1].rstrip("\n").split(delimiter)
tipe = [get_type(i) for i in tipe]
for i in database:
for j, jj in enumerate(i):
if get_type(jj) == "str": tipe[j] = "str"
if get_type(jj) == "float" and tipe[j] == "int": tipe[j] = "float"
return list((database,header,tipe))
def to_list(dataframe):
# -- DIBUKA KE PESERTA --
# mengembalikan bagian list of lists of items atau tabel data
# pada dataframe. Gunakan fungsi ini kedepannya jika ada keperluan
# untuk akses bagian data/tabel pada dataframe.
# parameter:
# dataframe (list, list, list): sebuah dataframe yang merupakan 3-tuple
# return (list): list of lists of items
return dataframe[0]
def get_column_names(dataframe):
# -- DIBUKA KE PESERTA --
# dataframe[1] adalah berisi list of column names. Gunakan fungsi ini
# kedepannya jika ada keperluan untuk akses daftar nama kolom pada
# sebuah dataframe.
# parameter:
# dataframe (list, list, list): sebuah dataframe yang merupakan 3-tuple
# return (list): list of column names
return dataframe[1]
def get_column_types(dataframe):
# -- DIBUKA KE PESERTA --
# dataframe[2] adalah berisi daftar tipe data dari
# setiap kolom tabel. Hanya ada tiga jenis tipe data,
# yaitu "str", "int", dan "float"
# parameter:
# dataframe (list, list, list): sebuah dataframe yang merupakan 3-tuple
# return (list): list of type names
return dataframe[2]
def head(dataframe, top_n=10):
# -- DIBUKA KE PESERTA --
# top_n baris pertama pada tabel!
# Mengembalikan string yang merupakan representasi tabel
# (top_n baris pertama) dengan format:
# kolom_1| kolom_2| kolom_3| ...
# -------------------------------------------
# value_11| value_12| value_13| ...
# value_21| value_22| value_23| ...
# ... ... ...
# Space setiap kolom dibatasi hanya 15 karakter dan right-justified.
# parameter:
# dataframe (list, list, list): sebuah dataframe
# top_n (int): n, untuk penampilan top-n baris saja
# return (string): representasi string dari penampilan tabel.
# Jangan pakai print()! tetapi return string!
cols = get_column_names(dataframe)
out_str = ""
out_str += "|".join([f"{col:>15}" for col in cols]) + "\n"
out_str += ("-" * (15 * len(cols) + (len(cols) - 1))) + "\n"
for row in to_list(dataframe)[:top_n]:
out_str += "|".join([f"{col:>15}" for col in row]) + "\n"
return out_str
def info(dataframe):
# Mengembalikan string yang merupakan representasi informasi
# dataframe dalam format:
# Total Baris = xxxxx baris
# Kolom Tipe
# ------------------------------
# kolom_1 tipe_1
# kolom_2 tipe_2
# ...
# Space untuk kolom dan tipe adalah 15 karakter, left-justified
# parameter:
# dataframe (list, list, list): sebuah dataframe
# return (string): representasi string dari info dataframe
# TODO: Implement
out = "Total Baris = {} baris".format(len(get_column_names(dataframe))) + "\n\n"
out += "{:<15}{:<15}".format("Kolom", "Tipe") + "\n"
out += "-" * (15 * 2 + 2) + "\n"
for i in range(len(get_column_names(dataframe))):
out += "{:<15}{:<15}\n".format(
get_column_names(dataframe)[i], get_column_types(dataframe)[i]
)
return out
def satisfy_cond(value1, condition, value2):
# -- DIBUKA KE PESERTA --
# parameter:
# value1 (tipe apapun yang comparable): nilai pertama
# condition (string): salah satu dari ["<", "<=", "==", ">", ">=", "!="]
# value2 (tipe apapun yang comparable): nilai kedua
# return (boolean): hasil perbandingan value1 dan value2
if condition == "<":
return value1 < value2
elif condition == "<=":
return value1 <= value2
elif condition == ">":
return value1 > value2
elif condition == ">=":
return value1 >= value2
elif condition == "!=":
return value1 != value2
elif condition == "==":
return value1 == value2
else:
raise Exception(f"Operator {condition} tidak dikenal.")
def select_rows(dataframe, col_name, condition, value):
# Mengembalikan dataframe baru dimana baris-baris sudah
# dipilih hanya yang nilai col_name memenuhi 'condition'
# terkait 'value' tertentu.
# Gunakan/Call fungsi satisfy_cond(value1, condition, value2) yang
# sudah didefinisikan sebelumnya!
# contoh:
# select_rows(dataframe, "umur", "<=", 50) akan mengembalikan
# dataframe baru dengan setiap baris memenuhi syarat merupakan
# item dengan kolom umur <= 50 tahun.
# Exceptions:
# 1. jika col_name tidak ditemukan,
# raise Exception(f"Kolom {col_name} tidak ditemukan.")
# 2. jika condition bukan salah satu dari ["<", "<=", "==", ">", ">=", "!="]
# raise Exception(f"Operator {condition} tidak dikenal.")
# parameter:
# dataframe (list, list, list): sebuah dataframe
# col_name (string): nama kolom sebagai basis untuk selection
# condition (string): salah satu dari ["<", "<=", "==", ">", ">=", "!="]
# value (tipe apapun): nilai untuk basis perbandingan pada col_name
# return (list, list, list): dataframe baru hasil selection atau filtering
# TODO: Implement
out = dataframe
if col_name not in out[1]:
raise Exception(f"kolom {col_name} tidak ditemukan")
for i in out[0]:
if (
satisfy_cond(
float(i[get_column_names(out).index(col_name)]),
condition,
float(value),
)
) == False:
out[0].remove(i)
return out
def select_cols(dataframe, selected_cols):
# Mengembalikan dataframe baru dimana kolom-kolom sudah
# dipilih hanya yang terdapat pada 'selected_cols' saja.
# contoh:
# select_cols(dataframe, ["umur", "nama"]) akan mengembalikan
# dataframe baru yang hanya terdiri dari kolom "umur" dan "nama".
# Exceptions:
# 1. jika ada nama kolom pada selected_cols yang tidak
# ditemukan,
# raise Exception(f"Kolom {selected_col} tidak ditemukan.")
# 2. jika select_cols adalah list kosong [],
# raise Exception("Parameter selected_cols tidak boleh kosong.")
# parameter:
# dataframe (list, list, list): sebuah dataframe
# selected_cols (list): list of strings, atau list yang berisi
# daftar nama kolom
# return (list, list, list): dataframe baru hasil selection pada
# kolom, yaitu hanya mengandung kolom-
# kolom pada selected_cols saja.
# TODO: Implement
out = dataframe
if selected_cols == []:
raise Exception("Parameter selected_cols tidak boleh kosong")
for i in selected_cols:
if i not in out[1]:
raise Exception(f"kolom {selected_cols} tidak ditemukan")
index = 0
while index < len(out[1]):
if out[1][index] not in selected_cols:
out[1].remove(out[1][index])
out[2].remove(out[2][index])
for i in out[0]:
i.remove(i[index])
elif out[1][index] in selected_cols:
index += 1
return out
def count(dataframe, col_name):
# mengembalikan dictionary yang berisi frequency count dari
# setiap nilai unik pada kolom col_name.
# Tipe nilai pada col_name harus string !
# Exceptions:
# 1. jika col_name tidak ditemukan,
# raise Exception(f"Kolom {col_name} tidak ditemukan.")
# 2. jika tipe data col_name adalah numerik (int atau float),
# raise Exception(f"Kolom {col_name} harus bertipe string.")
# 3. jika tabel kosong, alias banyaknya baris = 0,
# raise Exception("Tabel kosong.")
# Peserta bisa menggunakan Set untuk mengerjakan fungsi ini.
# parameter:
# dataframe (list, list, list): sebuah dataframe
# col_name (string): nama kolom yang ingin dihitung rataannya
# return (dict): dictionary yang berisi informasi frequency count
# dari setiap nilai unik.
# TODO: Implement
if get_type(col_name) == "int" or get_type(col_name) == "float":
raise Exception(f"Kolom {col_name} harus bertipe string")
if col_name not in dataframe[1]:
raise Exception(f"kolom {col_name} tidak ditemukan.")
out = {}
index = dataframe[1].index(col_name)
for i in dataframe[0]:
if i[index] not in out:
out[i[index]] = 1
elif i[index] in out:
out[i[index]] += 1
return out
def mean_col(dataframe, col_name):
# Mengembalikan nilai rata-rata nilai pada kolom 'col_name'
# di dataframe.
# Exceptions:
# 1. jika col_name tidak ditemukan,
# raise Exception(f"Kolom {col_name} tidak ditemukan.")
# 2. jika tipe data col_name adalah string,
# raise Exception(f"Kolom {col_name} bukan bertipe numerik.")
# 3. jika tabel kosong, alias banyaknya baris = 0,
# raise Exception("Tabel kosong.")
# parameter:
# dataframe (list, list, list): sebuah dataframe
# col_name (string): nama kolom yang ingin dihitung rataannya
# return (float): nilai rataan
index = dataframe[1].index(col_name)
mean = 0.0
out = 0
for i in dataframe[0]:
mean += float(i[index])
out = mean / len(dataframe[0])
return out
def show_scatter_plot(x, y, x_label, y_label):
# -- DIBUKA KE PESERTA --
# parameter:
# x (list): list of numerical values, tidak boleh string
# y (list): list of numerical values, tidak boleh string
# x_label (string): label pada sumbu x
# y_label (string): label pada sumbu y
# return None, namun fungsi ini akan menampilkan scatter
# plot dari nilai pada x dan y.
# Apa itu scatter plot?
# https://chartio.com/learn/charts/what-is-a-scatter-plot/
plt.scatter(x, y)
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.show()
def scatter(dataframe, col_name_x, col_name_y):
# fungsi ini akan menampilkan scatter plot antara kolom col_name_x
# dan col_name_y pada dataframe.
# pastikan nilai-nilai pada col_name_x dan col_name_y adalah angka!
# Exceptions:
# 1. jika col_name_x tidak ditemukan,
# raise Exception(f"Kolom {col_name_x} tidak ditemukan.")
# 2. jika col_name_y tidak ditemukan,
# raise Exception(f"Kolom {col_name_y} tidak ditemukan.")
# 3. jika col_name_x BUKAN numerical,
# raise Exception(f"Kolom {col_name_x} bukan bertipe numerik.")
# 4. jika col_name_y BUKAN numerical,
# raise Exception(f"Kolom {col_name_y} bukan bertipe numerik.")
# parameter:
# dataframe (list, list, list): sebuah dataframe
# col_name_x (string): nama kolom yang nilai-nilainya diplot pada axis x
# col_name_y (string): nama kolom yang nilai-nilainya diplot pada axis y
# Call fungsi show_scatter_plot(x, y) ketika mendefinisikan fungsi
# ini!
# return None
# TODO: Implement
if col_name_x not in dataframe[1]:
raise Exception(f"Kolom {col_name_x} tidak ditemukan")
if col_name_y not in dataframe[1]:
raise Exception(f"Kolom {col_name_y} tidak ditemukan")
data_x, data_y, index_x, index_y = (
[],
[],
dataframe[1].index(col_name_x),
dataframe[1].index(col_name_y),
)
for i in dataframe[0]:
data_x.append(float(i[index_x]))
data_y.append(float(i[index_y]))
show_scatter_plot(data_x, data_y, col_name_x, col_name_y)
def main():
dataframe = read_csv("abalone.csv")
scatter(dataframe,"Length","Height")
if __name__ == "__main__":
main()Editor is loading...
Leave a Comment