اذهب إلى المحتوى

لوحة المتصدرين

  1. Chihab Hedidi

    Chihab Hedidi

    الأعضاء


    • نقاط

      4

    • المساهمات

      2064


  2. Khaled Osama3

    Khaled Osama3

    الأعضاء


    • نقاط

      4

    • المساهمات

      1580


  3. Mustafa Suleiman

    Mustafa Suleiman

    الأعضاء


    • نقاط

      3

    • المساهمات

      13209


  4. كمال صالح2

    كمال صالح2

    الأعضاء


    • نقاط

      3

    • المساهمات

      117


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 01/02/24 في كل الموقع

  1. السلام عليكم هذا الكود يعمل بشكل متاز علي vs code ولكن عند نقله لموقع leetcode تظهر مشكله var addTwoNumbers = function(l1, l2) { l11 = Number(l1.join('')); l22 = Number(l2.join('')); ar = l11 + l22; console.log(ar) var myarr = String(ar).split("").reverse().map((ar) => { return Number(ar) }) return myarr };
    1 نقطة
  2. من المفترض أن يعمل معك الكود التالي بدون مشكلة: var addTwoNumbers = function(l1, l2) { l11 = Number(l1.join('')); l22 = Number(l2.join('')); ar = l11 + l22; console.log(ar) var myarr = String(ar).split("").reverse().map((ar) => { return Number(ar) }) return myarr }; addTwoNumbers([2,4,6], [3,5,6])
    1 نقطة
  3. في node js، نستعمل أحيانا cookie session في نظام المصادقة (authorization). كيف يكون هذا الإستعمال عند تطوير النظم الخلفية و تجربته مع postman. شكرا
    1 نقطة
  4. قم بإضافتهم من الخانة الخاصة بالـ cookies اسف الزر send : ثم قم بإضافة الدومين الذي تريد تشغيل ملفات الارتباط عليه وضاف ال cookies التي تريدها للدومين :
    1 نقطة
  5. ولكنه يمرر مصفوفات ف السؤال [2,4,6] مثلا هذه مصفوفه فيجب ان تعمل
    1 نقطة
  6. مرحبا كمال، اذا كانت قاعدة البيانات تتصل بدون أي مشاكل، أرفق ملف المشروع للإطلاع عليه أكثر. بالتوفيق.
    1 نقطة
  7. للاسف لازال الخطاء مستمر
    1 نقطة
  8. مرحبا كمال، حاول استخدام هذا الكود وتأكد من أن جميع علامات PHP تأتي بالترتيب الصحيح: <?php $server = 'DESKTOP-PJDLJNR'; $database = 'Legacy'; $username = ''; $password = ''; $connection = new PDO("sqlsrv:Server=$server;Database=$database", $username, $password); if (!$connection) { die(print_r(sqlsrv_errors(), true)); } $sql_query = 'SELECT * FROM Problemss'; $statement = $connection->query($sql_query); ?> <table border="1" width="100%"> <tr> <th>تم</th> <th>الحلول</th> <th>المشكلة</th> <th>م</th> <th>الرقم</th> </tr> <?php while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { ?> <tr> <td><?php echo $row['تم']?></td> <td><?php echo $row['الحلول']?></td> <td><?php echo $row['المشكلة']?></td> <td><?php echo $row['م']?></td> <td><?php echo $row['الرقم']?></td> </tr> <?php } ?> </table> <?php $connection = null; // إغلاق الاتصال بقاعدة البيانات ?> بالتوفيق إن شاء الله.
    1 نقطة
  9. لازال يتبقى خطاء استاذي القدير :
    1 نقطة
  10. الأمر طبيعي، على ما أظن أنك تحاول تمرير رقمين للدالة كالتالي: addTwoNumbers(3, 5) ولن تعمل ميثود join على الأرقام بل تعمل على المصفوفات فقط، كالتالي: const elements = ['Fire', 'Air', 'Water']; console.log(elements.join()); // Expected output: "Fire,Air,Water" console.log(elements.join('')); // Expected output: "FireAirWater" console.log(elements.join('-')); // Expected output: "Fire-Air-Water"
    1 نقطة
  11. لا داعي لإنشاء متغيرات A و B، بما أننا سنقوم بدمج selected_column_1 و selected_column_2 مباشرة, يفضل إعادة تعيين الفهرس مرة واحدة بعد الدمج لتجنب أي مشاكل. selected_column_1 = df.iloc[8::2, [0,1,2,cl3,cl4,cl5,cl6]] selected_column_2 = df.iloc[9::2, [2,cl3,cl4,cl5,cl6]] self.Table = pd.concat([selected_column_1, selected_column_2], axis=1, ignore_index=True) self.Table.reset_index(drop=True, inplace=True)
    1 نقطة
  12. مرحبا كمال، يبدو أن هناك خطأ في تركيبة كود PHP الخاص بك، بحيث أن العبارة print_r($row); يجب أن تكون خارج الحلقة وقبل جدول HTML، و أيضا يجب عليك إغلاق علامة PHP بشكل صحيح قبل بدء كود HTML. هذا كود ال php بعد التصحيح: <?php $server = 'DESKTOP-PJDLJNR'; $database = 'Legacy'; $username = ''; $password = ''; $connection = new PDO("sqlsrv:Server=$server;Database=$database", $username, $password); if (!$connection) { die(print_r(sqlsrv_errors(), true)); } $sql_query = 'SELECT * FROM Problemss'; $statement = $connection->query($sql_query); ?> <table border="1" width="100%"> <tr> <th>تم</th> <th>الحلول</th> <th>المشكلة</th> <th>م</th> <th>الرقم</th> </tr> <?php while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { ?> <tr> <td><?php echo $row['تم']?></td> <td><?php echo $row['الحلول']?></td> <td><?php echo $row['المشكلة']?></td> <td><?php echo $row['م']?></td> <td><?php echo $row['الرقم']?></td> </tr> <?php } $connection = null; // close the connection ?> </table> تأكد من استبدال القيم المؤقتة لـ $username و $password بالقيم الفعلية لاعتمادك على قاعدة البيانات. بالتوفيق إن شاء الله @كمال صالح محمد
    1 نقطة
  13. يبدو انك تضع في الكود فهل يواجهك نفس الخطأ المسبق ام خطأ اخر ؟
    1 نقطة
  14. عفواً أخي هل لك أن توضح لي التعديل على هذا الكود import customtkinter import tkinter as tk from tkinter import filedialog, messagebox, ttk import pandas as pd from pathlib import Path class App(customtkinter.CTk): def __init__(self): super().__init__() self.title("App-v1") self.grid_columnconfigure(0, weight = 1) self.grid_rowconfigure(1, weight = 1) customtkinter.set_appearance_mode("dark") customtkinter.set_default_color_theme("green") Menu(self) def File_dialog(self): self.filename = filedialog.askopenfilename(initialdir="C:\\Users\\Cakow\\PycharmProjects\\Main", title="Open file okay?", filetypes=(("text files", "*.xlsx"),("all files", "*.*"))) self.label_file["text"] = self.filename return None def Load_excel_data(self): file_path = self.label_file["text"] try: excel_filename = r"{}".format(file_path) if excel_filename[-4:] == ".csv": df = pd.read_csv(excel_filename) else: df = pd.ExcelFile(excel_filename) self.optionmenu1.configure(values = df.sheet_names) self.qq = df.sheet_names self.label2["text"] = df.sheet_names except ValueError: tk.messagebox.showerror("Information", "The file you have chosen is invalid") return None except FileNotFoundError: tk.messagebox.showerror("Information", f"إختر ملف أولاً {file_path}") return None def optionmenu_callback(self,choice): self.label2.configure(text=choice) def lod_Frame(self,cl3,cl4,cl5,cl6,xa,xb): df = pd.read_excel(self.filename,sheet_name=self.label2["text"],header=None) selected_column_1 = df.iloc[8::2, [0,1,2,cl3,cl4,cl5,cl6]] selected_column_1.reset_index(drop=True) selected_column_2 = df.iloc[9::2, [2,cl3,cl4,cl5,cl6]] selected_column_2.reset_index(drop=True, inplace=True) A = pd.DataFrame(selected_column_1) B = pd.DataFrame(selected_column_2) self.Table=pd.concat([A,B],axis=1) repeated_values1 = [] repeated_values2 = [] for i in range(len(self.Table)): repeated_values1.append(df.iloc[xa,xb]) repeated_values2.append(df.iloc[3,4]) self.Table['إسم المادة'] = repeated_values1 self.Table['العام الدراسي'] = repeated_values2 self.Table.fillna(0, inplace=True) self.Table['1أكبر_قيمة'] = self.Table.iloc[:, [5,6]].max(axis=1) self.Table['2أكبر_قيمة'] = self.Table.iloc[:, [10,11]].max(axis=1).apply(lambda x: 50 if x > 50 else x) self.Table['3أكبر_قيمة'] = self.Table.apply(lambda row: row.iloc[14] if row.iloc[15] == 0 else row.iloc[15] if 0 < row.iloc[15] <= 50 else None, axis=1) return self.Table def lod_data(self): App() a1= self.lod_Frame(3,4,5,6,6,3) a1 = a1.reset_index(drop=True) a2= self.lod_Frame(7,8,9,10,6,7) a2 = a2.reset_index(drop=True) a3= self.lod_Frame(11,12,13,14,6,11) a3 = a3.reset_index(drop=True) a4= self.lod_Frame(15,16,17,18,6,15) a4 = a4.reset_index(drop=True) a5= self.lod_Frame(19,20,21,22,6,19) a5 = a5.reset_index(drop=True) a6= self.lod_Frame(23,24,25,26,6,23) a6 = a6.reset_index(drop=True) a7= self.lod_Frame(27,28,29,30,6,27) a7 = a7.reset_index(drop=True) a8= self.lod_Frame(31,32,33,34,6,31) a8 = a8.reset_index(drop=True) a9= self.lod_Frame(35,36,37,38,6,35) a9 = a9.reset_index(drop=True) a10= self.lod_Frame(39,40,41,42,6,39) a10 = a10.reset_index(drop=True) a11= self.lod_Frame(43,44,45,46,6,43) a11 = a11.reset_index(drop=True) a12= self.lod_Frame(47,48,49,50,6,47) a12 = a12.reset_index(drop=True) a13= self.lod_Frame(51,52,53,54,6,51) a13 = a13.reset_index(drop=True) a14= self.lod_Frame(55,56,57,58,6,55) a14 = a14.reset_index(drop=True) a15= self.lod_Frame(59,60,61,62,6,59) a15 = a15.reset_index(drop=True) #self.Table = self.Table.reset_index() rtb=pd.concat([a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15],axis=0, ignore_index=True) # self.Table.to_excel("ALL2025.xlsx",sheet_name=self.label2["text"]) with pd.ExcelWriter('ALL2030.xlsx',if_sheet_exists="overlay",mode='a') as writer: rtb.to_excel(writer, sheet_name=self.label2["text"],header=None,index=False) class Menu(customtkinter.CTkFrame,App): def __init__(self, master): super().__init__(master) self.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="ew") self.columnconfigure(0, weight = 1) self.rowconfigure(1, weight = 1) self.configure(border_width=1,border_color="#0087f2") self.create_widgets() def create_widgets(self): self.button1 = customtkinter.CTkButton(self, text = 'File_dialog',command=self.File_dialog) self.button1.grid(row = 0, column = 3, padx=(10, 10), pady=(10, 10), sticky="e") self.label_file = ttk.Label(self, text="") self.label_file.grid(row = 0, column = 0, padx=(10, 10), pady=(10, 10), sticky="e") self.button2 = customtkinter.CTkButton(self, text = 'Load_excel',command=self.Load_excel_data) self.button2.grid(row = 0, column = 2, padx=(10, 10), pady=(10, 10), sticky="e") self.label2 = ttk.Label(self, text="") self.label2.grid(row = 1, column = 0, padx=(10, 10), pady=(10, 10), sticky="e") self.optionmenu1 = customtkinter.CTkOptionMenu(self,values=["إختر ورقة العمل"], font=customtkinter.CTkFont(family="Calibri", size=12, weight="bold")) self.optionmenu1.grid(row=0, column=1, padx=(10, 10), pady=(10, 10), sticky="e") self.optionmenu1.configure(command=self.optionmenu_callback) self.button3 = customtkinter.CTkButton(self, text = 'RUN',command=self.lod_data) self.button3.grid(row = 1, column = 3, padx=(10, 10), pady=(10, 10), sticky="e") app = App() app.mainloop()
    1 نقطة
  15. السلام عليكم أريد حل لهذا الخطأ pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects حيث أريد أن أقوم بضم DataFrame على المحور x على سبيل المثال مثل هذا In [1]: df1 = pd.DataFrame( ...: { ...: "A": ["A0", "A1", "A2", "A3"], ...: "B": ["B0", "B1", "B2", "B3"], ...: "C": ["C0", "C1", "C2", "C3"], ...: "D": ["D0", "D1", "D2", "D3"], ...: }, ...: ...: ) ...: In [2]: df2 = pd.DataFrame( ...: { ...: "A": ["A4", "A5", "A6", "A7"], ...: "B": ["B4", "B5", "B6", "B7"], ...: "C": ["C4", "C5", "C6", "C7"], ...: "D": ["D4", "D5", "D6", "D7"], ...: }, ...: ...: ) ...: In [3]: df3 = pd.DataFrame( ...: { ...: "A": ["A8", "A9", "A10", "A11"], ...: "B": ["B8", "B9", "B10", "B11"], ...: "C": ["C8", "C9", "C10", "C11"], ...: "D": ["D8", "D9", "D10", "D11"], ...: }, ...: ...: ) ...: In [4]: frames = [df1, df2, df3] In [5]: result = pd.concat(frames)
    1 نقطة
  16. الخطأ الذي تواجهه يحدث عندما يكون لديك أعمدة متكررة في DataFrame الخاص بك، مما يؤدي إلى فشل عملية إعادة التسمية (Reindexing) لحل هذا الخطأ، يمكنك إضافة ignore_index=True عند استخدام دالة concat و يمكنك تغيير السطر البرمجي الأخير ليصح كالتالي: result = pd.concat(frames, ignore_index=True) بهذه الطريقة، ستقوم pandas بإعادة ترقيم الفهارس بشكل فريد بدلا من محاولة استخدام الفهارس الحالية، مما يمنع حدوث الخطأ الذي تواجهه.
    1 نقطة
  17. يختلف ذلك حسب الدورة التعليمية التي قمت بالإشتراك بها وأعتقد أنك تقصد الدورات الموجود بأكاديمية حسوب ولكن يمكنك التقديم على فرص العمل المتوفره على مواقع التوظيف مثل بعيد و linkedin و العديد من المواقع الأخرى كما أنه يوجد الكثير من مواقع العمل الحر مثل مستقل والتي تكون في البداية صعبة نسبياً ولكن بعد ذلك يمكنك الإعتماد على منصات العمل الحر فقط بشكل جيد وهناك الكثير من الطرق الأخرى لذلك حاول فقط الحصول على الخبرة في المجال الخاص بك وحاول تنفيذ المشاريع التي توضح مدى خبرتك وبما أنك مشترك بإحدي دورات حاسوب فإنه يجب ذكر أن فريق أكاديمية حسوب يقدم الدعم للخريجين للمساعدة في الحصول على فرص عمل. وفي حال عدم تحقيق نجاح في الحصول على وظيفة، يتم استرداد قيمة الدورة بالكامل بدون أي مشكلة. هذا يعكس التزامهم بمساعدة الطلاب في بناء مستقبل مهني ناجح بما يتناسب مع توقعاتهم.
    1 نقطة
  18. وعليكم السلام الخطأ هنا يقول أن إطارات البيانات التي تم توحيدها (a1, a2, a3) لديها مؤشرات مكررة. فيجب تعيين الفهرس مجددًا بشكل فريد لكل إطار بيانات قبل الدمج: a1 = a1.reset_index(drop=True) a2 = a2.reset_index(drop=True) a3 = a3.reset_index(drop=True) self.Table = pd.concat([a1, a2, a3], axis=0) يجب استخدام `ignore_index=True` أثناء عملية الدمج: باستخدام ignore_index=True سيقوم pandas بإعادة تعيين الأرقام بشكل متلاحق دون تكرار، حتى لو كانت مكررة في الأصل. فهذا سيؤدي لدمج البيانات بشكل صحيح دون أخطاء. self.Table = pd.concat([a1, a2, a3], axis=0, ignore_index=True) تأكد من أن المؤشرات فريدة لكل إطار بيانات قبل الدمج لتجنب هذه المشكلة.
    1 نقطة
  19. السلام عليكم وجدت كثيرا من المبرمجين يرشحون node.js ك backend بدلا من اي لغه اخري بقوه ولكن عند الدخول عل وظائف العمل الحر لا اجد غير php لا أجد ruby ولا python ولا node.js
    1 نقطة
  20. 1 نقطة
  21. جزاك الله خيرا. طريقة حفظ الأعمدة دون طباعتها في الجدول، يمكنك حفظ قيم الأعمدة في متغيرات منفصلة بدلاً من إضافتها للجدول مباشرة. مثال: # حساب العمود الأول col1_values = Table.iloc[:, [5,6]].max(axis=1) # حساب العمود الثاني col2_values = Table.iloc[:, [10,11]].max(axis=1).apply(lambda x: 50 if x > 50 else x) # استخدام القيم في العملية التالية Table['3أكبر_قيمة'] = Table.apply(lambda row: col1_values[i] if col2_values[i]==0 else col2_values[i] if 0 < col2_values[i] <= 50 else None, axis=1) فهذا يحافظ على القيم دون إضافتها للجدول. اما هذا الكود محتاج بعض التعديلات: 1. لا تضف القيم مباشرة للمتغيرات repeated، بل احفظها في متغيرات مستقلة 2. استخدم المؤشر i للوصول لقيم المتغيرات داخل الدوال 3. حساب قيم الأعمدة خارج الدوال وليس داخلها repeated_values1 = [] repeated_values2 = [] col1_values = [] col2_values = [] for i in range(len(Table)): repeated_values1.append(df.iloc[6,3]) repeated_values2.append(df.iloc[3,4]) Table['إسم المادة'] = repeated_values1 Table['العام الدراسي'] = repeated_values2 Table.fillna(0, inplace=True) col1_values = Table.iloc[:, [5,6]].max(axis=1) col2_values = Table.iloc[:, [10,11]].max(axis=1).apply(lambda x: 50 if x > 50 else x) Table['3أكبر_قيمة'] = Table.apply(lambda row: col1_values[i] if col2_values[i]==0 else col2_values[i] if 0 < col2_values[i] <= 50 else None, axis=1)
    1 نقطة
  22. الطريق الأسهل هو أن تصبح لديك نسبة في أسهم الشركة كإمتياز لك من ضمن إمتيازات الوظيفة، وبعض الشركات توفر ذلك، والطريقة الثانية هي شراء الأسهم ولكن الأمر بحاجة إلى مبالغ كبيرة لكي تحصل على نسبة جيدة من الشركة. لكن إذا أردت الاستثمار، فيمكنك الاستثمار في أسهم البورصة في السعودية وأمريكا خاصًة S&P 500 ، لكن تجنب الاستثمار في الأسهم الخاصة بالبنوك بسبب الربا. الأسهم، كيف يمكنني الاستثمار به؟ الاستثمار، ما هي أنواعه؟ وما هو أفضلها في وقتنا الحالي؟
    1 نقطة
  23. هياكل البيانات data structures -أو تدعى بنى المعطيات أحيانًا- مصطلح يتكرر كثيرًا في علوم الحاسوب خصوصًا والبرمجة عمومًا ويعد من المصطلحات المعقدة البسيطة أو السهلة الممتنعة كما أن الكثير يخلط بينه وبين أنواع البيانات أو لا يكاد يميز بينهما، ولابد على أي داخل لمجال علوم الحاسوب ومن يريد تعلم البرمجة أن يفهم هذا المصطلح جيدًا لأنه الأساس الذي سيستند عليه في بناء بقية المفاهيم الأخرى اللاحقة. بناء على ذلك، جاء هذا المقال ليكون تعريفًا بهياكل البيانات وأنواعها بأسلوب بسيط سهل مدعوم بالصور التوضيحية كل هيكل بيانات بالإضافة إلى ذكر ميزات وعيوب بعض الأنواع، كما يتناول هذا المقال التعريف بأهمية هياكل البيانات وأهم تطبيقاتها والفرق بينها وبين أنواع البيانات، لذا لنبدأ! ما هي هياكل البيانات؟ تُعَدّ هياكل البيانات data structures من أهم المفاهيم التأسيسية في مجال علوم الحاسوب، فهي ببساطة مجموعة من الوسائل والطرق المستعملة في ترتيب البيانات في ذاكرة الحاسوب بهدف التعامل معها بكفاءة وفعالية وتسهيل إجراء العمليات عليها، وتوجد هناك أنواع أساسية ومتطورة من هياكل البيانات وجميعها مصمَّمة لتنظيم البيانات لاستخدامها في هدف محدَّد. أهمية هياكل البيانات data structures أحب بداية ضرب مثال يوضح هياكل البيانات وأهميتها وهو أننا نستعمل هذا المفهوم في حياتنا اليومية بصورة أو بأخرى، لنفترض أن البيانات تمثل ملابسنا، فهل نرمي الملابس في خزانة واحدة كلها؟ لا بالطبع لأن إخراج بنطال معين آنذاك سيستغرق وقتًا من البحث للعثور عليه وإخراج بل نضع الألبسة بطريقة معينة في عدة خزانات وسحابات وبطرق مختلفة بحيث نصل إلى بنطال أو قميص محدد بمجرد طلبه فورًا آنيًا دون تأخير. الأمر نفسه مع ترتيب البهارات وأوعية المطبخ والكتب وكل شيء حولنا تقريبًا. هذا بالضبط ما يحصل عند كتابة كلمة في محرك البحث لتظهر لك اقتراحات عد قد تطابق تمامًا ما تنوي كتابته في غضون أجزاء من الثانية، فهل تساءلت كيف تمكن محرك البحث من البحث في كم البيانات الضخم الموجودة في الإنترنت ووصل إلى النتيجة؟ لا يمكن ذلك بآلية الرمي العشوائي في مكان واحد التي ذكرناها في ترتيب الملابس تلك بل بتنظيم البيانات ضمن هياكل بيانات تشبه الأوعية والخزانات تسهل الوصول إليها بأسرع ما يمكن. نظرًا لتطور التطبيقات وازدياد تعقيدها وازدياد كمية البيانات الضخم يومًا بعد يوم والذي تتطلب عملية معالجتها معالجات هائلة السرعة، فكان لا بد من تنظيم البيانات وإدارتها بكفاءة في هياكل البيانات تمثل أوعية تخزين وتنظيم لها، إذ يمكن أن يساعد استخدام هياكل البيانات المناسبة في توفير قدر كبير من الوقت أثناء إجراء عمليات عليها مثل تخزين البيانات أو استرجاعها أو معالجتها، وبالتالي وصول أسرع إلى الذاكرة وتوفير في استهلاك العتاد من عمليات معالجة وطاقة للحاسوب. من الجدير بالذكر أيضًا أنّ هياكل البيانات ضرورية لتصميم خوارزميات فعالة والتي سنراها في تطبيقات هياكل البيانات ضمن هذا المقال. الفرق بين أنواع البيانات وهياكل البيانات يبدو لك أنّ أنواع البيانات Data Types وهياكل البيانات Data Structures وجهان لعملة واحدة لأنّ كلاهما يتعامل مع طبيعة البيانات وتنظيمها، ولكن في الحقيقة الأول يشرح نوع وطبيعة البيانات في حين يمثِّل الآخر التجميعات التي تُخزَّن تلك البيانات فيها، وفيما يلي الفروق الأساسية بين نوع البيانات وهيكل البيانات. يمثِّل نوع البيانات ماهية البيانات التي سيجري التعامل معها مثل أن تكون البيانات أعداد أو سلاسل نصية أو رموز …إلخ. في حين يُعَدّ هيكل البيانات تجميعةً collection تحوي تلك البيانات وهناك عدة أنواع من الهياكل تناسب مختلف أنواع البيانات. يحدد نوع البيانات ما يترتب عليه من عمليات تطبق على تلك البيانات مثل العمليات الرياضية على الأعداد وعمليات المعالجة على النصوص وهكذا أما هياكل البيانات فتحدد كيفية تخزين البيانات والوصول إليها والبحث فيها وغيرها من العمليات كما تدرس كيفية تحسين الأداء في تلك العمليات. يأخذ نوع البيانات شكل التنفيذ المجرد abstract implementation الذي يُعرَّف من خلال لغات البرمجة نفسها، في حين يُنفَّذ هيكل البيانات تنفيذًا حقيقيًا concrete implementation بحيث يُنشأ ليكون متوافقًا مع التصميم الذي يحتاجه المبرمج بالحجم الذي يريده وبنوع البيانات التي سيحتويها ضمن تطبيقه. يسمى نوع البيانات بأنه عديم القيمة dataless لأنه لا يخزِّن قيمة البيانات وإنما يمثِّل فقط نوع البيانات التي يمكن تخزينها، في حين يستطيع هيكل البيانات الاحتفاظ بأنواع مختلفة من البيانات مع قيمتها في كائن واحد. تحدد أنواع البيانات مع المتغيرات مثلًا في لغات البرمجة عند تعريفها، في حين تحتاج إلى كتابة بعض الخوارزميات لإسناد قيم البيانات إلى المتغيرات عند استخدام هيكل بيانات مثل عمليتَي الإضافة Push والجلب Pop للبيانات. لا يُكترث للزمن عند استخدام نوع البيانات، في حين يؤخذ بالحسبان عند استخدام هيكل البيانات (يطلق عليه تعقيد زمني BigO). تطبيقات هياكل البيانات يكاد لا يخلو أي تطبيق أو برنامج أو خوارزمية برمجية من وجود هيكل بيانات أو بنية معطيات تساعده في تحقيق الهدف المرجو منه، ومن هذه التطبيقات ما يلي: تنظيم البيانات في ذاكرة الحاسوب. تمثيل المعلومات في قواعد البيانات. خوارزميات معالجة البيانات مثل معالجة النصوص. خوارزميات تحليل البيانات مثل data minar. خوارزميات البحث في البيانات مثل محرك البحث. خورزميات توليد البيانات مثل مولِّد الأعداد العشوائية. خوارزميات ضغط البيانات وتفك ضغطها مثل المعتمدَة في برنامج zip. خوارزميات تشفير البيانات وتفك تشفيرها مثل المعتمدَة في نظام الأمان. البرامج التي تدير الملفات والمجلدات مثل مدير الملفات. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن أنواع هياكل البيانات في لغات البرمجة تنقسم هياكل البيانات إلى هياكل بيانات أولية Primitive وهياكل بيانات غير أولية Non Primitive أو هياكل بيانات معقدة وكل منها يضم عدة أقسام سنشرحها تباعًا. هياكل البيانات الأولية Primitive هي هياكل البيانات الأساسية والبسيطة والتي تُستخدَم لتخزين قيمة من جزء واحد فقط ذات نوع محدَّد، ويندرج تحت هذا النوع ما يلي: integer: من أجل الأعداد الصحيحة مثل العدد 15. character: من أجل محرف واحد فقط. float: من أجل الأعداد العشرية. real: من أجل الأعداد الحقيقية. boolean: من أجل القيم البوليانية والذي يأخذ إحدى القيمتين؛ إما محققة true أو غير محققة false. ملاحظة: قد تتساءل عن هياكل تخزين النصوص، وهي في الحقيقة تدخل ضمن الهياكل الغير أولية أن النصوص مجموعة من الحروف والرموز التي تدعى محارف characters لذا تخزن عادة ضمن مصفوفة وأحيانًا تضيف لغات البرمجة نوعًا خاصًا لها يدعى string سلسلة نصية أو لا يضيف وتكون بالشكل char[]‎ وما تراه [] يدل على هيكل مصفوفة. يوجد شيء خاص يدعى مؤشر pointer والمشهور في بعض اللغات البرمجية مثل سي C وسي بلس بلس ++C، إذ يُعَدّ مكانًا في الذاكرة ويخزِّن عنوان المتغير الذي يشير إليه والشي الخاص فيه أنه يملك نوع بيانات والذي يجب أن يطابق نوع البيانات الذي يشير إليها. ملاحظة: ممكن تسمية هياكل البيانات التي تخزن الأعداد العشرية باسم double (عدد عشري مضاعف الدقة) أو float (عدد عشري) عوضًا عن real بصورة عامة ويكمن الاختلاف حسب اللغة البرمجية في عدد الخانات العشرية الممكن تخزينها، أي عدد الخانات بعد الفاصلة العشرية، بالإضافة إلى الحجم في الذاكرة وأخيرًا طريقة التعريف declaration، ففي لغة سي شارب #C يكون تعريف المتغير من نمط float كما يلي: float x = 1.5f; أما تعريفه عندما يكون من نمط double، فيكون كما يلي: double x = 1.5; ملاحظة: يطلق أحيانًا على هياكل البيانات الأولية أنواع البيانات Data Type. هياكل البيانات غير الأولية هي هياكل البيانات التي تُستخدَم من أجل التخزين المعقّد والتي يمكنها أن تحمل أكثر من قيمة في بنيتها، وتنقسم إلى هياكل بيانات خطية Linear وهياكل بيانات غير خطية Non Linear. هياكل البيانات الخطية تكون هياكل البيانات خطيّةً إذا كانت عناصرها تشكل تسلسلًا فيما بينها بحيث يرتبط كل عنصر فيها بعنصر سابق وعنصر لاحق ضمن مستوى واحد وفي مسار واحد، ومن هذه الهياكل ما يلي: المصفوفة Array القائمة المترابطة Linked List المكدس Stack الرتل Queue المصفوفة تُعَدّ المصفوفة الخطية array أو المصفوفة ذات البعد الواحد أبسط أنواع الهياكل الخطية، ويمكن تشبيهها بقائمة من عدد محدود من العناصر التي تمتلك النوع ذاته، ويكون بعدها -أو طولها- هو عدد العناصر التي تملكها، كما تُخزّن في الذاكرة بحجم ثابت وبمواقع متجاورة. كل عنصر من عناصر هذه المصفوفة الخطية يملك فهرسًا للوصول إليه، وعادةً ما يبدأ الفهرس بالعدد 0 أي يكون فهرس العنصر الأخير هو n-1 في مصفوفة بعدها n، وفي بعض لغات البرمجة يكون فهرس البداية هو العدد 1 مثل لغة باسكال، وفيما يلي صورة توضِّح هذه البنية: ملاحظات: يُنظَر إلى السلسلة النصية string على أنها مصفوفة أحادية من المحارف، أي كلمة Hello هي سلسلة نصية وهي مصفوفة طولها 5 مكوّنة من خمسة عناصر بحيث يمثِّل كل عنصر محرفًا من المحارف كما أشرنا سابقًا. المصفوفة ثنائية البعد هي أيضًا مجموعة من المتغيرات المفهرسة التي تحتوي على النوع نفسه من البيانات ولكن تخزين البيانات فيها يكون على صورة جدول له أعمدة وأسطر، بحيث يمكن الوصول إلى العنصر في هذه المصفوفة من خلال فهرسين أحدهما يحدِّد السطر والآخر يحدِّد العمود. من الجدير بالذكر أنّ بُعد المصفوفة ثابت في بعض لغات البرمجة وبالتالي يجب معرفة عدد العناصر قبل تعريفها فإذا أردت تغيير البُعد وإضافة عناصر جديدة، فستحتاج إلى مصفوفة جديدة ببُعد جديد لتنقل إليها العناصر السابقة وبعدها تضيف العناصر الجديدة إليها، كما أنّ إضافة عنصر ما في مكان ما مملوء مسبقًا أي في وسط المصفوفة مثلًا سيستهلك الكثير من العمليات، إذ ستحتاج إلى إزاحة العناصر اللاحقة ليصبح له مكانًا فارغًا، ويُعَدّ ذلك من عيوب استخدام المصفوفات. هنالك لغات أخرى لا تشترط تحديد عدد عناصر المصفوفة ولكنها تستهلك آنذاك عمليات كثيرة وتكون مكلفة لعمليات المعالجة أما تلك التي تحدد عدد العناصر مسبقًا فذلك عائد إلى توفير عمليات المعالجة. ملاحظة: قد تجد كلمة static ساكن وكلمة dynamic متحرك لتصنيف الأنواع الغير خطية ولكن شرحهما متقدم جدًا يحتاج إلى مقال بأكمله وستحتاج إليه عند التعمق كثيرًا وليس في البداية. القائمة المترابطة تُعَدّ القائمة المترابطة linked list مجموعةً من العقد التي تخزَّن في الذاكرة بمواقع غير متجاورة، وكل عقدة من عقد القائمة مرتبطة بالعقدة المجاورة لها بمؤشر عدا العقدة الأخيرة التي يكون المؤشر فيها عبارة عن Null. تسمح هذه البنية بإدراج عناصر جديدة أو حذف عناصر موجودة سابقًا بسهولة وهذا ما يميزها عن المصفوفات؛ أما سرعة الوصول، فتُعَدّ المصفوفات أسرع لأنه يكفي ذكر الفهرس الرابع على عكس القائمة المترابطة التي يجب البدء فيها من الرأس ثم المرور على العناصر بالتتالي إلى حين الوصول إلى العنصر الرابع. من الجدير بالذكر أنّ القائمة المترابطة تحتاج إلى مساحة إضافية في الذاكرة من أجل المؤشر الذي يرتبط بالعنصر، وهذا عيب آخر من عيوب القوائم المترابطة. يوجد نوع متطور من القوائم المترابطة وهو القوائم المترابطة المزدوجة Doubly Linked List، إذ ترتبط كل عقدة بمؤشرَين أحدهما يربطها بالعقدة السابقة ويسمى عادةً prev والآخر يربطها بالعقدة التالية ويسمى عادةً next، وبالتالي تحتاج هذه القائمة إلى مساحة إضافية في الذاكرة لامتلاكها على مؤشر إضافي، وبالمثل يكون المؤشر prev في عقدة الرأس Null ومؤشر next في العقدة الأخيرة هو Null. يوجد نوع أخير من القوائم المترابطة وهو القوائم المترابطة الدائرية Circular Linked Lists والتي تُعَدّ تطويرًا عن المفردة بحيث يشير مؤشر next الخاص بعقدة النهاية إلى عقدة الرأس. كما توجد القوائم الدائرية المزدوجة بحيث يشير مؤشر prev الخاص بعقدة الرأس إلى عقدة النهاية ويشير مؤشر next الخاص بعقدة النهاية إلى عقدة الرأس، وبالتالي لا تحتوي القوائم المترابطة الدائرية على مؤشرات Null. المكدس يُعَدّ المكدِّس stack هيكل بيانات خطية يتبع ترتيبًا محددًا في تنفيذ عمليات الحذف والإضافة، والترتيب يكون LIFO أي الذي يدخل آخرًا يخرج أولًا Last In First Out، والذي يميز المكدس هنا هو دخول العناصر وخروجها من قمة المكدِّس أي من جهة واحدة. تدخل -أو تُضاف- العناصر إلى المكدِّس عن طريق عملية وحيدة وخاصة وهي دفع Push وبالمثل فإنها تخرج منه -أو تُحذَف- عن طريق عملية وحيدة وخاصة أيضًا وتدعى إخراج Pop، وتوجد أيضًا عمليتان خاصتان بالمكدِّس وهما Top -أو Peek- التي تعيد القيمة الموجودة في قمة المكدِّس دون حذفها، والعملية الأخرى هي عملية IsEmpty التي تُعيد القيمة true إذا كان المكدِّس فارغًا. عند إضافة عنصر إلى مكدِّس ممتلئ لا يستوعب المزيد من العناصر فستحصل حالة طفحان المكدِّس overflow؛ أما عند إجراء عملية الحذف من مكدِّس فارغ، فسنواجه حالة طفحان أو تجاوز الحد الأدنى underflow (قعر المكدس). الرتل يُعَدّ الرتل queue أحد هياكل البيانات الخطية شبيه بالمكدس لامتلاكه عمليات خاصة للحذف والإضافة ولكنه يختلف عنه في مكان الحذف والإضافة كما سنرى. يدعى الرتل أو الطابور بـ FIFO أي الذي يدخل أولًا يخرج أولًا First In First Out بحيث يكون الدخول -أو الإضافة- من الجهة الخلفية rear والخروج -أو الحذف- من الجهة الأخرى أي الأمامية front (كما يحصل عند الوقوف ضمن الطوابير تمامًا لشراء شيء ما)، وتحدث الإضافة عن طريق عملية ENQUEUE أما عملية الحذف فتكون عن طريق عملية DEQUEUE. يتميز الرتل أيضًا بامتلاكه عمليات خاصة وهي العملية IsFull التي تُعيد true إذا كان الرتل ممتلئًا، والعملية IsEmpty التي تُعيد true إذا كان الرتل فارغًا، والعملية Front التي تُعيد العنصر الأمامي من الرتل، بالإضافة إلى العملية Rear التي تُعيد العنصر الخلفي من الرتل. هياكل البيانات غير الخطية لا تحتوي هياكل البيانات غير الخطية -أو المتشعبة- على أيّ تسلسل محدد يربط جميع عناصرها، إذ يمكن أن يكون لكل عنصر أكثر من مسار ليرتبط بالعناصر الأخرى، كما أنّ العناصر الموجودة ضمن هذه الهياكل لا يمكن اجتيازها أو المرور عليها في جولة واحدة أو باستخدام حلقة برمجية واحدة. وأهم ما يميّز هذا النوع على الرغم من صعوبة التنفيذ موازنةً بالهياكل الخطية التي يزداد فيها تعقيد الوقت مع ازدياد حجم البيانات أنه يُعد أكثر كفاءة في استخدام الذاكرة وأكثر سرعة في تطبيق العمليات مثل عمليات البحث، ومن هذه الهياكل: الشجرة الرسم البياني الشجرة تُعَدّ الشجرة tree هيكل بيانات متعدد المستويات وتُعرَّف على أنها مجموعة من العقد التي تحتوي فيما بينها على علاقة هرمية بحيث تسمى العقدة العليا بالعقدة الجذر، كما تحتوي كل عقدة على أب وحيد، في حين يمكن أن يكون لها أكثر من ابن أو تابع. تسمى العقد التي تتفرع من عقدة معينة بأبناء children تلك العقدة والتي بدورها تدعى بالعقدة الأب parent، في حين تسمى العقد التي لا تمتلك أبناء بالأوراق leaves. تمتلك الشجرة عدة أنواع وهي: الشجرة الثنائية binary tree شجرة البحث الثنائية binary search tree شجرة AVL شجرة R-B شجرة البادئات الشجرة الثنائية الشجرة الثنائية binary tree هي شجرة بيانات تمتلك كل عقدة فيها -ما عدا الأوراق- على عقدَتي ابن فقط وهما الابن الأيمن والابن الأيسر. شجرة البحث الثنائية شجرة البحث الثنائية binary search tree أو BST اختصارًا هي شجرة ثنائية تحقق خاصيتان أساسيتان وهما أنّ العقد الواقعة في الفرع اليميني تكون أكبر من العقدة الأب والعقد الواقعة في الفرع اليساري تكون أصغر من العقدة الأب، مع ضمان وجود ابنَين لكل عقدة وعدم تكرار العقد. شجرة AVL تُعَدّ اختصارًا لـ Adelson-Velskii Tree إذ يُعَدّ أديسون Adelson وفيلسكي Velskii مخترعَيها للحفاظ على توازن شجرة البحث الثنائي وذلك لمنع تدهورها إلى قائمة مرتبطة عندما تحتوي الشجرة بأكملها على الشجرة الفرعية اليسرى فقط أو على الشجرة اليمنى فقط مما سينعكس سلبًا على أداء الشجرة، إذ يمكن استخدام سلسلة من عمليات التدوير بحيث تُحدَّد في كل عملية عقدة جذر إلى حين الوصول إلى شجرة بعقدة جذر معينة بحيث تكون متوازنة أي ارتفاع الشجرة اليسرى مساويًا لارتفاع الشجرة اليمنى، ويمكن القول هنا أنّ شجرة AVL هي شجرة BST تحقق شرط التوازن، علمًا أنّ ارتفاع الشجرة هو أكبر عمق موجود لها. شجرة R-B تعني الشجرة الحمراء والسوداء Red-Black tree وهي شجرة بحث ثنائية لها خصائص تميزها بحيث تحتوي كل عقدة فيها على بت تخزين يشير إلى لون العقدة والتي يمكن أن تكون حمراء أو سوداء فقط، كما أنّ عقدة الجذر والعقد الأوراق سوداء دائمًا، وإذا كانت العقدة حمراء فيجب أن يكون أبناءها سود، وأخيرًا يجب أن تحتوي جميع المسارات من عقدة إلى أحفادها العدد نفسه من العقد السوداء، فإذا تحقق ما سبق، فستكون الشجرة شجرة بحث ثنائية متوازنة. شجرة البادئات تُعَدّ شجرة البادئات Prefix tree نوعًا من أشجار البحث وتعرف أيضًا بالشجرة الرقمية أو tri كما تُعرَف بشجرة القاموس وتُستخدَم في البحث عن الكلمات بصورة عامة بما أنها مكوَّنة من أحرف الهجاء، وأهم ما يميزها أنّ جذرها لا يحتوي على أيّ محرف. الكومة تُعَدّ الكومة Heap بنية معطيات شجرية تمتلك خاصة الكومة وهي وجود أسلوب ترتيب متَّبع بين العقد الآباء والعقد الأبناء مثل أن يكون كل أب أكبر من جميع أبنائه وتسمى حينها بالكومة العظمى Max-Heap أو أن يكون كل أب أصغر من جميع أبنائه وتسمى حينها بالكومة الصغرى Min-Heap، وتُستخدَم الكومة بكثرة في خوارزميات الترتيب، كما تتميز الكومة بأنّ جميع مستوياتها ممتلئة بالكامل عدا المستوى الأخير، وفيما يلي صورة توضِّح كومة صغرى. الرسم البياني يختلف الرسم البياني graph أو المبيان عن الشجرة في عدم احتوائه على جذر ومن الممكن أن تتصل العقد مع بعضها باتجاه واحد directed graph أو بالاتجاهين معًا Bi-directional أو بدون اتجاه undirected، كما أنّ طبيعة العلاقات بين العقد في هذا النوع ليست ذات طبيعة هرمية، كما تسمى العقد بالرؤوس vertices والروابط التي بينها تسمى بالحواف أو الأضلاع edges ويكون عدد كل من الرؤوس والأضلاع محدودًا. يكون الزوج (1,2) في الرسم البياني الموجَّه والذي يدل على وجود اتجاه من الرأس 1 إلى الرأس 2 مختلفًا عن الزوج (2,1)، كما تُرمَز مجموعة الرؤوس في هذا النوع بالرمز V ومجموعة الأضلاع بالرمز E ويُستخدَم هذا النوع من البنى في تمثيل الشبكات الواقعية مثل شبكة الهاتف المحمول أو شبكات التواصل الاجتماعي مثل الفيسبوك على سبيل المثال. التقطيع Hashing يُعَدّ التقطيع Hashing أو التجزئة تحسينًا لهياكل البيانات السابقة في بعض التطبيقات التي تحتاج إلى ترتيب بياناتها بواسطة أعداد كبيرة وفريدة موجودة ضمن هذه البيانات مثل ترتيب سجلات المرضى ضمن المستشفيات بناءً على أرقام هواتفهم والتي تُعَدّ مفاتيحًا فريدةً unique لهذه السجلات، ويكون ذلك من خلال الاستعانة بدالة تدعى دالة التقطيع hashing function والتي تحوِّل هذا المفتاح الفريد إلى عدد صغير وصحيح بحيث يكون فهرسًا لجدول جديد يدعى جدول التقطيع hashing table. من الممكن أن يكون فهرس جدول التقطيع هو ذاته رقم هاتف المريض بحيث يكون طوله هو أكبر رقم هاتف موجود ضمن السجلات زائد واحد بما أنّ الفهرسة تبدأ من الصفر، وبالتالي نحصل على سرعة وصول عالية لأيّ سجل من خلال رقم الهاتف الخاص به، ولكن سيتسبب ذلك بتواجد فجوات gaps بين العناصر لعدم الحاجة لوجود جميع أرقام الهواتف المحتملة وبالتالي زيادة حجم التخزين في الذاكرة، لذا تُستخدَم دالة التقطيع لحل هذه المشكلة، وعندها يكون جدول التقطيع مصفوفةً يمثِّل كل عنصر فيها مؤشرًا على السجل الذي يحتوي على رقم الهاتف -في مثالنا- والذي تكون نتيجة تطبيق دالة التقطيع عليه هي فهرس هذا العنصر. من الضروري التأكد من أنّ دالة التقطيع لا تعطي النتيجة ذاتها لأكثر من مفتاح، فإذا كانت دالة التقطيع مثلًا هي تأخذ فقط الرقم الأخير من رقم الهاتف، فسيكون لرقمَي الهاتف 45451 و 56561 على سبيل المثال النتيجة نفسها أي العدد 1 وبالتالي سيحدث تصادم في جدول التقطيع الذي فهرسه العدد 1، وأحد حلول هذه المشكلة أن يكون كل عنصر من جدول التقطيع مؤشرًا على قائمة مترابطة تحتوي على السجلات التي نتيجة تطبيق دالة التقطيع على أرقام هواتفها هي ذاتها. ليكن لدينا الأعداد التالية 12 – 17 – 29 – 6 – 30 – 31 – 4 – 8، فإذا كان فهرس جدول التقطيع هو ذاته العدد المعطى، فسنحتاج إلى جدول بحجم 32، ولكن فعليًا نحتاج إلى 8 أماكن للتخزين وبالتالي سنحصل على فجوات وهدر في الذاكرة، لذا سنلجأ إلى دالة التقطيع والتي ستعطي آحاد العدد المُعطى، وبالتالي ستكون نتيجتها 2 – 7 – 9 – 6 – 0 – 1 – 4 – 8 عند تطبيقها على الأعداد السابقة على الترتيب، بحيث يُخزَّن العدد 12 في العنصر الذي فهرسه هو العدد 2 وهكذا، وبالتالي سنحتاج إلى جدول تقطيع بحجم 8 بدلًا من 32 كما يلي: 12 17 29 6 30 31 4 8 2 7 9 6 0 1 4 8 يمكن تقليص حجم هذا الجدول ليصبح 4 بتحسين دالة التقطيع، بحيث يكون الفهرس هو باقي قسمة كل عدد من الأعداد المعطاة على العدد 4، ولكن ستكون نتيجة الأعداد 17 و 19 هي الفهرس 1، أي سيحدث تصادم، ويمكن حل هذه المشكلة بجعل كل عنصر من عناصر جدول التقطيع مؤشرًا على قائمة مترابطة من الأعداد التي باقي قسمتها على العدد 4 هو فهرس هذا العنصر، أي كما في الشكل التالي: يمكن زيادة حجم جدول التقطيع في المستقبل، كما أنّ هذه التقنية هي الأكثر استخدامًا في جوجل google. الخاتمة تعرَّفنا في هذا المقال على هياكل البيانات بكافة أنواعها مع إعطاء أمثلة توضيحية تساعدك على تخيل هذه البنى، بالإضافة إلى التطرق إلى ذكر أهميتها والفرق بينها وبين أنواع البيانات مع ذكر أهم تطبيقاتها. اقرأ أيضًا مقدمة إلى مفهوم البيانات الضخمة Big Data هياكل البيانات: القوائم المترابطة Linked lists والأشجار Trees في لغة سي C هياكل البيانات: الكائنات والمصفوفات في جافاسكريبت تصميم قواعد البيانات table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; }
    1 نقطة
×
×
  • أضف...