Переглядав якісь старі емейли і знайшов цікавий кусок коду десь десятилітньої давності. Це були часи, коли я ще був бона фіде вченим, жив в Матлабі, а продакшн код, типу статистичних алгоритмів томографічного відновлення гігантських 3D картинок писав на C. І раптом мені довелося шукати роботу в індустрії, і дали мені зробити домашнє завдання. Ну, є така фішка, особливо давніше була, при пошуках датазнавців дають програмувальний проект. Ну, там, прочитати дані з CSV файлів, пару перетворень, класифікатор, все таке. Зараз -- роботи на півгодини.
Який було би зробити просто, але одна засада - треба було використовувати Python, а я про нього тоді не знав приблизно нічого. Взагалі. Про бібліотеки, про саме існування якихось бібліотек. Відкрив сайт python.org, почав заглядати в документацію... І написав! Правда, тиждень грався, але навіть в час вклався, бо на ту домашку ліміту не було. В процесі щось вивчив, наприклад, з нуля на коліні написав naive Bayes класифікатор для змішаних числових і категорійних змінних (а от нема такого в їхніх бібліотеках, бо надто кастомізовано).
Послав в ту компанію. Чувак відповів -- data science aspects -- superb. Але взяти вони мене не візьмуть, бо у них трохи інший підхід до програмування.
І дивлячись на код нижче, я розумію, чому.... :)
Але, тим не менше, як на людину, яка вчора вперше відкрила документацію Пітону, і обчислює все в Сі, мені, знаєте, навіть не соромно.
А, код -- прочитати CSV табличку.
Який було би зробити просто, але одна засада - треба було використовувати Python, а я про нього тоді не знав приблизно нічого. Взагалі. Про бібліотеки, про саме існування якихось бібліотек. Відкрив сайт python.org, почав заглядати в документацію... І написав! Правда, тиждень грався, але навіть в час вклався, бо на ту домашку ліміту не було. В процесі щось вивчив, наприклад, з нуля на коліні написав naive Bayes класифікатор для змішаних числових і категорійних змінних (а от нема такого в їхніх бібліотеках, бо надто кастомізовано).
Послав в ту компанію. Чувак відповів -- data science aspects -- superb. Але взяти вони мене не візьмуть, бо у них трохи інший підхід до програмування.
І дивлячись на код нижче, я розумію, чому.... :)
Але, тим не менше, як на людину, яка вчора вперше відкрила документацію Пітону, і обчислює все в Сі, мені, знаєте, навіть не соромно.
А, код -- прочитати CSV табличку.
def read_csv_with_names(fname): try: fid = open(fname, 'r') except: raise NameError('Cannot read fname '+fname) Nrow, Ncol = -1, 0 rows, columns, values = {}, {}, [] for s in fid: s = s.strip().split(',') if(Nrow == -1): for z in s[1:]: columns[z] = Ncol Ncol += 1 # done dealing with the first file else: # we know we are not in the first row rows[s[0]] = Nrow v = [] for z in s[1:]: if z: v.append(float(z)) else: v.append(float('inf')) values.append(v) Nrow += 1 # done reading fid.close() return Nrow, Ncol, rows, columns, valuesUPDATE: Якщо неясно, то вищенаписаний код -- це спроба скопіювати логіку Сі там, де від неї лише шкода. Він ігнорує існування бібліотек, безпричинно перевизначає код помилки), і, найгірше, обчислює абсолютно непотрібні змінні, які там для того, щоби потім звертатися до даних в таблиці як до матриці, за числовими індексами. Словом, зараз я те ж саме пишу так:import pandas pandas.read_csv(filename,index=0).fillna(float('inf'))І навіть абсолютно функціонально ідентичний до мого колишнього метод виглядає так:import pandas def read_csv_with_names(fname): df = pandas.read_csv(fname, index_col=0).fillna(float('inf')) return (df.shape[0], df.shape[1], {v:k for k,v in enumerate(df.index)}, {v:k for k,v in enumerate(df.columns)}, df.values.tolist())
no subject
Date: 2025-03-29 06:51 am (UTC)no subject
Date: 2025-03-29 04:48 pm (UTC)Це був стартап в СФ, який пробував писати ML методи аналізу тримірних картинок всяких медичних сканів. Я концептуально їм дуже підходив -- нескромно вважаю, що на той момент я був серед десятка кращих спеціалістів з реконструкції таких картинок в регіоні, і чи не єдиний on the job market. Не тому, що я такий розумний, а тому, що спеціалізація непопулярна і в регіоні майже не представлена.
Вся лажа в тому, що їм потрібна була людина, яка би прямо зараз почала працювати над реальними проектами, а не вчилася півроку, переписуючи з нуля кожен метод. Я в апдейті написав, як було правильно :)
no subject
Date: 2025-03-29 07:28 pm (UTC)no subject
Date: 2025-03-29 11:11 pm (UTC)Там, насправді, дофіга цікавого і в плані код писати -- просто, заодно з усякою математикою.
Я, наприклад, мав один проект: 3D reconstruction (узагальнений Радон-трансформ, воно) через оптимізацію, але не у вигляді тримірної матриці вокселів, а на тетраедральну сітку з адаптивною геометрією вузлів. На жаль, після того, як я зробив прототип і опублікував статтю, далі воно не пішло -- там потрібна була команда і, в ідеалі, інтерес в індустрії. А шкода...
no subject
Date: 2025-03-30 07:10 am (UTC)no subject
Date: 2025-03-29 11:07 am (UTC)s = s.strip().split(',')Пайтон може на ходу змінювати типи змінних? З рядка зробити масив?
no subject
Date: 2025-03-29 04:52 pm (UTC)Тобто, тут тип змінної не міняється, залишається текстом. Зі зміною типу в правильному Пітоні треба би було так:
s = [c if k=0 else float(c) for k, c in enumerate(s.strip().split(','))]no subject
Date: 2025-03-30 07:03 pm (UTC)spit— це типова операція в різних мовах. Розбиває рядок за роздільником на масив підрядків.Результат (тобто масив) у цьому коді записано назад до тієї самої змінної
s, котра спочатку була рядком. Тому я й спитав про зміну типу.no subject
Date: 2025-03-30 08:16 pm (UTC)я мав на увазі, що спліт робить з рядка масив рядків, а каст на числові змінні стається пізніше
no subject
Date: 2025-03-29 11:53 am (UTC)А я ні
no subject
Date: 2025-03-29 04:54 pm (UTC)Якщо метафорично, вони шукали муляра, а не людину, яка, почувши, що треба збудувати стіну, йде читати, як збирати глину і самому випалювати цеглу.
no subject
Date: 2025-03-29 09:59 pm (UTC)no subject
Date: 2025-03-29 11:20 pm (UTC)Це, приблизно, як нинішній програміст, замість писати код на рівні абстракцій, почне писати звертання до операцій памʼяті ...
no subject
Date: 2025-03-29 11:32 pm (UTC)no subject
Date: 2025-03-30 12:11 am (UTC)Але переважно звик :)
no subject
Date: 2025-03-29 08:54 pm (UTC)Якщо сильно прискіпуватися:
* занадто процедурний,
* відсутність можливості іншої типізації даних (захардкожений float),
* захардкожена наявність header row,
* пряма робота з масивами скасовує можливість async aka lazy computation.
no subject
Date: 2025-03-29 11:20 pm (UTC)no subject
Date: 2025-03-29 11:58 pm (UTC)