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

ريم المهدي

الأعضاء
  • المساهمات

    127
  • تاريخ الانضمام

  • تاريخ آخر زيارة

إجابات الأسئلة

  1. إجابة ريم المهدي سؤال في الحصول على التصنيفات في GANs كانت الإجابة المقبولة   
    لقد وجدت نوع من انواع GANs يعمل على إنشاء صور و تصنيفات وهو ما يسمي ب Conditional Generative Adversarial Netowrks او cGANs، البرنامج السابق يستخدم فقط shallow GANs وهي أنواع الخوارزميات التي تختص فقط بإنشاء صور جديدة. 
    Answering this in case anyone else falls into the same trap
  2. إجابة ريم المهدي سؤال في طريقة حفظ البيانات في لغة بايثون كانت الإجابة المقبولة   
    يوجد عدد من الخيارات، منها أن يتم حفظ إسم اللاعب و درجته كمتغيرات في ملف خارجي و عند بدء اللعبة يتم إستدعاء و قراءة الملف لتحميل المتغيرات:
    import pickle name = 'Test'; score = [100]; pickle.dump([name, score], open("trial.p", "wb")) في البرنامج أعلاه تم إستخدام pickle library لحفظ المتغيرين الإسم و الدرجة في ملف إسمه trial.p و لتحميلهم مرة أخرى يمكن أن نقوم بالاتي:
    name, score = pickle.load(open("trial.p","rb")) print(name, score) لاحظ أن عملية الكتابة تستخدم ب wb mode وهو الذي يمكننا من الكتابة في الملف، و عند الإستدعاء نستخدم rb mode وهو للقراءة من الملف الذي تم فيه حفظ القيم trial.p.
  3. إجابة ريم المهدي سؤال في خطأ في كود مصفوفة ثنائية البعد في الجافا كانت الإجابة المقبولة   
    هنالك عدد من الأخطاء التي يمكن حلها:
    1- تعريف المصفوفة يكون بعد تحديد عدد الصفوف و الأعمدة،
    2- الأسماء لا يجب تكرارها في نفس البرنامج، لذا قمت بتعريف r , c بدلاً من row, column اللذان تم إستخدامهما من قبل، مع العلم أنه يمكن إستخدام نفس المتغيرات المعرفة بداخل الحلقة في حلقة أخرى،
    3- عمليات الطباعة الأخيرة تكون على مستوى مجموع القيم للصفوف وليس الأعمدة،
    4- إستخدام الدالة math.floor هو ما يمكننا من إيجاد قيم أعلى من صفر لملء المصفوفة بالقيم الجديدة،
    البرنامج المعدل يكون كالتالي:
    import java.util.Scanner; import static java.lang.Math.*; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); System.out.print("Enter # of rows "); int row =in.nextInt(); System.out.print("Enter # of columns "); int column=in.nextInt(); int matrix[][]=new int[row][column]; for (int r=0;r<matrix.length;r++){ for (int c=0;c<matrix[0].length;c++){ System.out.print("Enter row # "+(r+1)+" and column # "+(c+1)+": "); matrix[r][c]=in.nextInt(); } } System.out.println("Printing User Elements"); for (int r=0;r<matrix.length;r++){ for (int c=0;c<matrix[0].length;c++){ System.out.print(matrix[r][c]+" "); } System.out.println(" "); } System.out.println("Replacing elements with random numbers, done ..."); for (int r=0;r<matrix.length;r++){ for (int c=0;c<matrix[0].length;c++){ matrix[r][c]=((int)Math.floor(Math.random()*100)); } } System.out.println("Printing ..."); for (int r=0;r<matrix.length;r++){ for (int c=0;c<matrix[0].length;c++){ System.out.print(matrix[r][c]+" "); } System.out.println(" "); } int total=0; for (int r=0;r<matrix.length;r++){ for (int c=0;c<matrix[0].length;c++){ total+=matrix[r][c]; } } System.out.println("Printing the total of the elements"); System.out.println("Printing total by row:"); for (int r=0;r<matrix.length;r++){ int subtotal=0; for (int c=0;c<matrix[0].length;c++){ subtotal+=matrix[r][c]; } System.out.println("The sum of row "+(r+1)+" is " +subtotal); } } } قمت بإضافة عدد من عبارات الطباعة ليصبح البرنامج مقروء.
  4. إجابة ريم المهدي سؤال في إضافة عمود في مصفوفة numpy بقيم عشوائية كانت الإجابة المقبولة   
    هنالك خطوتين في هذا السؤال الأولى هي إنشاء البيانات العشوائية و الثانية هي عملية إضافة العمود أو الأعمدة الجديدة:
    import numpy as np N = 3 a = np.array([[1, 2,],[3, 4]]) b = np.random.random((N,a.shape[1])) np.ascontiguousarray(numpy.vstack([a, b]).T) في البرنامج السابق قمنا بإستيراد numpy و من ثم تعريف عدد القيم الجديدة التي نود إضافتها و مناداة الدالة random من مكتبة numpy.random وبعد تمرير الشكل إستخدمنا vstack لإلصاق القيم الجديدة بالمصفوفة a لكن لتسريع العملية إستخدمنا ascontiguousarray والتي تتعامل مع contiguous array في الذاكرة بالتالي فهي أسرع، لاحظ لنتيجة إختبار سرعات الدوال التالية:

  5. إجابة ريم المهدي سؤال في ظهور الخطأ ValueError: Input 0 of layer sequential_1 is incompatible with the layer أثناء تدريب شبكة CNN في keras كانت الإجابة المقبولة   
    وفي حال لم تكن تعرف عدد العينات في كل من المصفوفات المراد تحويل شكلها يمكنك القيام بالتالي:
    x_train = np.reshape(x_train, (-1, 28, 28, 1)) x_test = np.reshape(x_test, (-1, 28, 28, 1)) والان لاحظ أن البرنامج لن ينفذ و ينتج الخطأ التالي:
    ValueError: Shapes (60, 1) and (60, 10) are incompatible لتفادي ذلك يجب تحويل مصفوفات y_train, y_test إلى التمثيل المقابل لها في الone hot encoding بإستخدام دالة to_categorical لأن عملية التصنيف إلى 10 أصناف تتتطلب ذلك لاحظ keras.layers.Dense(10):
    y_train = to_categorical(y_train) y_test = to_categorical(y_test) والان البرنامج يصبح كالتالي:
    import numpy as np import keras from keras.models import Sequential from keras.layers import Dense , Activation, Dropout from keras.optimizers import Adam ,RMSprop from keras.models import Sequential from keras.utils.np_utils import to_categorical from keras.datasets import mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() print(x_train.shape, y_train.shape,x_test.shape, y_test.shape) x_train = np.reshape(x_train, (-1, 28, 28, 1)) x_test = np.reshape(x_test, (-1, 28, 28, 1)) print(x_train.shape, y_train.shape,x_test.shape, y_test.shape) # y تطبيق على قيم one hot encoding y_train = to_categorical(y_train) y_test = to_categorical(y_test) print(x_train.shape, y_train.shape,x_test.shape, y_test.shape) model = keras.models.Sequential([ keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28,28,1)), keras.layers.MaxPool2D(2,2), keras.layers.Conv2D(64, (3,3), activation='relu'), keras.layers.MaxPool2D(2,2), keras.layers.Flatten(), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(10, activation='softmax') ]) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(x_train, y_train, epochs=20,validation_data=(x_test, y_test), batch_size=60)  
  6. إجابة ريم المهدي سؤال في ما هي مزايا NumPy مقارنة بقوائم Python العادية؟ كانت الإجابة المقبولة   
    بالإضافة إلى ما ذكره @Ali Haidar Ahmad في إجابته يمكننا أيضاً أن نقول هنالك فوارق أخرى بين numpy arrays & lists:
    المصفوفات لها طول ثابت على عكس القوائم، و في حالة الإضافة للمصفوفة يتم مسح الأصلية و إنشاء واحدة أخرى بنفس الطول + 1. العناصر في القوائم يمكن أن تكون من أنواع مختلفة و لكن العناصر في المصفوفات تكون من نفس النوع، يمكن أن تحتوي عناصر مختلفة لكن لن يتم تنفيذ العمليات الحسابية مثلاً في هذه الحالة. يمكن للمصفوفات التعامل مع العمليات الحسابية و الإحصائية، و العمليات الجبرية و البحث على البيانات الضخمة بصورة أكثر كفاءة و أقل كود. from numpy import arange from timeit import Timer #تحديد عدد البيانات المدخلة Nelements = 10000 #إنشاء قائمة و مصفوفة بنفس الطول x = arange(Nelements) y = range(Nelements) #تعريف دالة الجمع لإستخدامها في قياس المدة الزمنية t_numpy = Timer("x.sum()", "from __main__ import x") t_list = Timer("sum(y)", "from __main__ import y") #طباعة الزمن الناتج من تنفيذ العملية print("numpy: %.3e" % (t_numpy.timeit(Nelements)/Nelements,)) print("list: %.3e" % (t_list.timeit(Nelements)/Nelements,)) البرنامج السابق عبارة عن نموذج يوضح الفرق في سرعة التعامل مع كل من المصفوفات و القوائم التي تصل إلى فرق 10 أضعاف السرعة للمصفوفات مقابل القوائم.
    numpy: 9.865e-06 list: 1.839e-04  
     
     
     
  7. إجابة ريم المهدي سؤال في لماذا يتم إعتبار دالة list.append بقيمة False في بايثون؟ كانت الإجابة المقبولة   
    سؤال جيد، هنالك العديد من الدوال، العبارات والقيم التي تمثل عبارة خاطئة منها العبارة المنطقية False نفسها، القيمة صفر لأي متغير، القائمة الفارغة[] empty dictionary {} و أيضاً العبارة None. راجع الأمثلة التالية:
    x = None if x: print('if x') else: print('if not') #if not x = {} if x: print('if x') else: print('if not') #if not x = [] if x: print('if x') else: print('if not') #if not x = 0 if x: print('if x') else: print('if not') #if not في الأمثلة السابقة نفذنا الشرط مع كل من ما تم ذكره سابقاً، و في حال كانت قيمة x تساوى 0,None,[],{} طبقنا شرط if x والتي تعني في حال كان الشرط صحيح if x == True نطبع عبارة if x (يمكنك إستبدالها بأي شي أخر ك True مثلاً لكن لم نستخدمها هنا لتفادي التشوش مع العبارات الصحيحة أو الخاطئة بوليانياً). لكن مثلا إن قمنا بإضافة أي عنصر في القائمة أو dictionary أو حتى تغيير قيمة x فإن النتيجة ستكون بطباعة الجملة الأولى الموجودة داخل شرط if، راجع المثال التالي:
    x = 42 if x: print('if x') else: print('if not') #if x و بالتعميم فإن الدالة append ترجع None فبذلك نفهم أن تحويلها للقيمة البوليانية هو ما سيعطينا قيمة false.
    x = [] print(bool(x)) print(bool(x.append(123))) print(bool(x)) False False True البرنامج أعلاه هو نفسه ما قمت بتطبيقه لكن مع إستدعاء الدالة bool التي ترجع القيمة البوليانية للمتغير أو الدالة و غيره.
    بعد تعريف القائمة الفارغة و التي عرفنا أن قيمتها البوليانية ستمثل False بعدها قمنا بنداء الدالة لتحديد القيمة الراجعة من عملية الإضافة والتي ستكون False و لكن القيمة البوليانية للقائمة بعد الإضافة تتغير من False إلى True.
     
  8. إجابة ريم المهدي سؤال في استخدام حلقة تكرار لا يتم تطبيقها على كل العناصر في بايثون؟ كانت الإجابة المقبولة   
    المشكلة تظهر لأن remove تقوم بحذف أول ظهور لأحد الحروف في القائمة، الحروف التي سيتم حذفها ستتأثر بطول القائمة و بالحروف الموجودة بها، و بما أن الحذف ينقص من عدد الحروف بالقائمة و العبارة return ترجع القائمة الجديدة فمن الأغلب أنه في بعض المرات التي ظهرت فيها بعض الحروف متتالية تم حذف إحداها و تم تمرير القائمة الجديدة مرة أخرى (inconsistency problem).
    يمكن حل المشكلة بإستخدام عدد من الطرق الأخرى، مثلاً list comprehension:
    def anti_vowel(c): vowels = ('a', 'e', 'i', 'o', 'u') return ''.join([l for l in c if l not in vowels]) anti_vowel("Hellooo, world! Woooords!") # Hll, wrld! Wrds! الناتج عبارة عن كل الحروف و علامات الترقيم ما عدا التي تم تحديدها في vowels set.
    يمكن أيضاً إستخدام regular expression، عن طريق إستخدام الدالة sub التي تقوم بالبحث عن واحد أو مجموعة حروف في نص محدد و إستبداله بما يتم تمريره في المدخل الثاني للدالة.
    import re def anti_vowel(s): return re.sub(r'[AEIOU]', '', s, flags=re.IGNORECASE) anti_vowel("Hellooo, world! Woooords!") لاحظ هنا تحديد مدخل أخير للدالة و التي يتغاضى فيها عن وجود الحروف الكبيرة أو الصغيرة (إختياري) و يبحث عن الأحرف المحددة بغض النظر عن نوعها.
    الطريقة الثالثة هي إستخدام translate وهي دالة تستقبل dictionary بالحروف التي سيتم إستبدالها و القيم الجديدة لها، راجع المثال التالي:
    dictionary = str.maketrans(dict.fromkeys('aeiouAEIOU')) "Hellooo, world! Woooords!".translate(dictionary) وفيه تم إستخدام maketrans لإنشاء mapping table من الحروف المدخلة كبيرها و صغيرها، حيث أن الحروف ستمثل المفاتيح بدون قيم values are None، و أخيراً نمرر الجدول لدالة الترجمة.
     
  9. إجابة ريم المهدي سؤال في ظهور الخطأ التالي ValueError: The least populated class in label has only 1 member, which is too few. The minimum number of groups for any class cannot be less than 2. أثناء محاولة تقسيم البيانات باستخدام train_test_split كانت الإجابة المقبولة   
    هذا الخطأ ينتج بالطبع حسب نوع البيانات المدخلة و توزيعها، أعلم عزيزي@Meezo ML أن هذا الخطأ ناتج عن إستخدام stratify والذي يمكنك التخلص منه فقط بالمسح، راجع السطر التالي:
    X,X_val, y, y_val=train_test_split(data,label,test_size=0.2) لكن دعنا نفهم لماذا نتج هذا الخطأ من الأساس، stratify هو عبارة عن مدخل لدالة التقسيم والذي يمكننا إستخدامه فقط في حالة البيانات التصنيفية categorical variables و الذي يقوم بتقسيم البيانات بين التدريب و التقييم training and validation بصورة تتناسب مع توزيع البيانات الأساسية، مثلاً إذا كان لدينا صنفين في y أحدهما يمثل 25% من البيانات و الأخر 75% فإن stratify تقوم بتقسيم البيانات بين التدريب و التحقق بنفس النسبة لكل من مجموعتي البيانات.
    from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split iris = load_iris() X = iris.data y = iris.target X1 = pd.DataFrame(X).drop(pd.DataFrame(X).index[10:50]).drop(pd.DataFrame(X).index[70:100]).drop(pd.DataFrame(X).index[140:]) y1 = pd.DataFrame(y).drop(pd.DataFrame(y).index[10:50]).drop(pd.DataFrame(y).index[70:100]).drop(pd.DataFrame(y).index[140:]) y1.value_counts() x_train, x_test, y_train, y_test = train_test_split(X1,y1,stratify=y1) اولاً قمنا بإستدعاء الدوال لتحميل بيانات Iris وتقسيم البيانات بإستخدام train_test_split و من ثم حملنا البيانات وقسمناها إلى مدخلات و مخرجات X,y و حذفنا عدد من السطور في كل من المدخلات و المخرجات (للتأكد من تنفيذ stratify، مع العلم أنها يمكن أن تعمل حتى لو كانت الأصناف متساوية كما في حالة Iris والتي يتساوى فيها التصنيفات بعدد 50 لكل صنف) الناتج من الحذف يعطي التقسيم التالي:
    2 40 1 20 0 10 بمعدل 40 عينة من الصنف الأول، 20 من الثاني و 10 من الأخير. و أخيراً عملية التقسيم تأخذ X1,y1 كمدخلات مع stratify الذي يستقبل y1 وبالتالي إن قمنا بطباعة أعداد التصنيفات في y_test سنحصل على نفس توزيع المدخلات.
    y_test.value_counts() 2 10 1 5 0 3  
  10. إجابة ريم المهدي سؤال في إيجاد الصفوف الفريدة في مصفوفة numpy كانت الإجابة المقبولة   
    يمكن إيجاد الصفوف الفريدة بأكثر من طريقة، منها بإستخدام unique كما هو موضح في الإجابة أعلاه، أو بإستخدام الدالة vstack كما في المثال التالي:
    import numpy as np a = np.array([ [1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0], [1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0]]) print(np.vstack({tuple(row) for row in a})) print(np.vstack(set(map(tuple, a)))) بعد إستدعاء الدالة numpy تم تعريف المصفوفة، و من بعدها الدالة vstack من numpy (التي تحول المدخل إلى مكدس رأسي) و بإستخدام خاصية المجموعة التي تقوم بإختيار القيم غير المكررة فقط من الصفوف الموجودة في المصفوفة a.
    أما في السطر الأخير فقد تم عمل نفس الشئ بتحويل الصفوف إلى مدخلات للمجموعة بإستخدام دالة map والتي تحول أي صف إلى tuple أولا و من ثم تنفذ عملية التحويل إلى مجموعة و في الأخير تحويل الناتج إلى مكدس رأسي.
    طريقة أخرى لإستخراج الصفوف الفريدة بإستخدام طريقة إقصاء الصفوف المكررة عن طريق الدالة drop_duplicates() والتي تستخدم مع dataframe، راجع البرنامج التالي:
    import pandas as pd pd.DataFrame(a).drop_duplicates().values والتي نحول فيها المصفوفة إلى dataframe لنتمكن من إستخدام الدالة الخاصة بالإقصاء و من ثم لتحويل الناتج إلى مصفوفة نستدعى الدالة values.
    لكن عزيزي @Fahmy Mostafa إن كنت تريد الحصول على أسرع طريقة، يمكنك التأكد بإستخدام العبارة timeit والتي تعطيك الزمن المتوسط (لأسرع 5 نتائج) من تنفيذ الدالة 1000 مرة، و حسب التنفيذ و الشرح الموضح في الموقع بأخر الإجابة vstack تعتبر أسرع طريقة:
    timeit np.vstack(set(map(tuple, a))) #10000 loops, best of 5: 25.1 µs per loop timeit np.vstack({tuple(row) for row in a}) #10000 loops, best of 5: 24.3 µs per loop timeit np.unique(a, axis=0) #10000 loops, best of 5: 107 µs per loop timeit pd.DataFrame(a).drop_duplicates().values #1000 loops, best of 5: 1.39 ms per loop يمكنك مراجعة الصورة التالية أيضاً:

     
    والتي توضح إختلاف سرعات التنفيذ للدوال المستخدمة في إيجاد الصفوف الفريدة، يمكنك مراجعة موقع GitHub لتتعرف على المزيد من التفاصيل.
     
  11. إجابة ريم المهدي سؤال في إضافة عمود جديد بناءً على قيم عمود موجود في numpy و pandas كانت الإجابة المقبولة   
    يمكننا إستخدام إحدى الطرق التالية:
    الطريقة الأولى: العبارة where والتي تستخدم لتطبيق الشروط مع البيانات الضخمة، وفيها يتم التحقق من شرط معين و تمرير قيمة ليتم إسنادها في العمود الجديد مقابل كل قيمة، و قيمة أخرى في حال عدم توفر الشرط، راجع المثال التالي:
    import pandas as pd import numpy as np df = pd.DataFrame({ 'Type': ['A', 'B', 'O', 'B'], 'Set': ['A', 'B', 'B', 'A']}) df['test'] = np.where(df['Set'] == 'A', 'group1', 'group2') df في البدء قمنا بإستدعاء المكتبات numpy , pandas ثم عرفنا dataframe يحتوى على العمودين و بياناتهما، أخيراً قمنا بتعريف عبارة where و التي تستقبل 3 متغيرات، الأولى عبارة عن الشرط، الثاني القيمة في حال تحقق الشرط، و الثالثة هي القيمة في حال عدم تحقق الشرط. في هذه الحالة الشرط يقوم بالتحقق من القيم في كل سطر لوحده و تطبيق القيمة المختارة في السطر المقابل له في العمود الجديد.
    الطريقة الثانية: هي بالتعويض بإستخدام شرط داخل دالة dataframe.loc والتي تحدد عدد من الأسطر بناء على ما بالقوسين المربعين، راجع المثال التالي:
    df.loc[df['Set'] == 'A', 'test'] = 'group1' df.loc[df['Set'] == 'B', 'test'] = 'group2' df في البرنامج السابق نقوم بإختيار القيم التي تحتوي على 'A' في عمود Set و من ثم إسناد القيمة group1 لها في العمود المسمي test، نفس الطريقة مطبقة بالسطر الثاني.
    الطريقة الثالثة: هي بإستخدام list comprehension وهي من أبسط الطرق التي تعتمد على إنشاء قائمة بناء على الشرط المتحقق في كل سطر من القيم الموجودة في Set، راجع المثال التالي:
    df['test'] = ['group1' if x =='A' else 'group2' for x in df['Set']] df الطريقة الرابعة: هي بإستخدام دالة map و التي تعتمد على المدخلات في شكل dictionary حيث أن كل القيم الممرة تمثل Keys and values و المفاتيح تمثل القيم في العمود Set و الvalues ترمز للقيم التي سيتم إدراجها في العمود الجديد test في حال توافقها مع إحدي المدخلات A أو B راجع البرنامج التالي:
    test ={'A' : 'group1', 'B' : 'group2'} df['test'] = df['Set'].map(test) df  
     
  12. إجابة ريم المهدي سؤال في لماذا يمكن للدالة تعديل بعض المدخلات بينما لا يتم تطبيق هذه التعديلات على المتغيرات في بايثون؟ كانت الإجابة المقبولة   
    لتعديل المتغيرات داخل الدوال أو أي موقع في البرنامج يجب أن نجعل المتغير مقروء لكل أجزاء البرنامج، يمكننا ذلك عن طريق إستخدام الكلمة المحجوزة global والتي نعرفها قبل تغيير قيمة x داخل الدالة f، لكن لنقوم بإستخدامها لا يجب تمريرها بالدالة فهي أصبحت مقروءة بصورة أتوماتيكية، راجع البرنامج التالي:
    def f(y): global x x = 1 y.append(3) print('In f():', x, y) x = 0 y = [0,1,2] print('Before:', x, y) f(y) print('After: ', x, y) لاحظ للتغيير بداخل الدالة f و جعل x متغير عام مرئي بداخل الدالة و يمكن الوصول لموقعه في الذاكرة و التعديل عليه، و من ثم إسناد قيمة x الجديدة، يجب أيضاً أن تنتبه لمسح x من إستدعاء الدالة f في السطر رقم 10. بالتالي النتيجة تصبح:
    Before: 0 [0, 1, 2] In f(): 1 [0, 1, 2, 3] After: 1 [0, 1, 2, 3]  
     
     
  13. إجابة ريم المهدي سؤال في كيف يمكنني استخراج الأرقام من هذه النصوص في بايثون؟ كانت الإجابة المقبولة   
    لاحظ أن بعض الدوال لا يمكنها إستخراج القيم السالبة و الأرقام المكتوبة بصورة علمية scientific writing مثل 0.000000123 والتي يمكن كتابتها في بايثون بصيغة 1.23E-7، للحصول على دالة أشمل يمكننا إستخراج الأرقام و العلامات مثل - (موجودة في الأرقام السالبة و الأرقام العلمية) من النص و تخطي أي قيم حرفية كالتالي:
    newstr = ''.join((ch if ch in '0123456789.-e' else ' ') for ch in s) بذلك نحصل على كل الأرقام مجمعة (نتيجة لإتخدام الدالة join) في شكل نص و بوجود فراغات ( الحروف التي تم تخطيها من قبل الشرط if) و نقوم بتحويل النص المحتوي على كل الأرقام الممكنة إلى قائمة بإستخدام split، كما يمكننا تحويل كل الأرقام إلى قيم كسرية (إختياري) كالتالي:
    listOfNumbers = [float(i) for i in newstr.split()] بذلك تكون كل الأرقام مخزنة في المتغير listOfNumbers.
×
×
  • أضف...