Вычисление произвольного факториала




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

9 Comments

  1. DrAku1a

    Круто! Давай ещё произвольные степени чисел, например — чему равно: (9#k8SjZc9Dxk9)#k8SjZc9Dxk9?

    Reply
  2. pwn

    Функция ниже, вроде тоже вычисляет факториал. Или это немного не то?

    &НаКлиенте
    Процедура ВычислитьФакториал(Команда)
    Факториал = 1;
    Пока Параметр > 0 Цикл
    Факториал = Факториал * Параметр;
    Параметр = Параметр — 1;
    КонецЦикла;
    Факториал = СтрЗаменить(Строка(Факториал), Символы.НПП, «»);
    Сообщить(Факториал);
    Сообщить(СтрДлина(Факториал));
    КонецПроцедуры

    Показать

    Reply
  3. pwn

    Понял в чем «подвох». Спасибо за решение.

    Reply
  4. catsam

    (3) pwn, вот-вот — я сначала тоже так отреагировал. А потом _внезапно_ вспомнил про такую штуковину, как переполнение. =) Кстати, 1С ещё мягко это обрабатывает — просто обрезает левую часть результата. А вот когда не 1С считает, а, например, та же C# — там падение гарантировано. =)))

    (1) DrAku1a, а это тоже задача на переполнение — весь необходимый код уже имеется тут. Зачем же плодить лишние сущности? =)

    Reply
  5. alex_4x

    Однозначно — ПЛЮС.

    Еще бы возведение в произвольную степень, деление, просто умножение, вычисление числа Пи! и поиск простых чисел.

    Кстати в поиске простых чисел есть некий подход, который позволяет пропускать те диапазоны, где простого числа не может быть.

    Кстати есть интересная форма записи чисел (любых) система счисления, основанная на простых числах

    Каждому разряду соответствует простое число и в разряде — 0 или 1. Таким образом любое число может быть представлено как сумма N количества РАЗНЫХ простых чисел. При этом длина записи для чисел больших порядков становится короче, чем например при использовании двоичной системы.

    Reply
  6. ildarovich

    Для саморазвития, конечно, полезно, но вот вопрос: а знал ли автор, затевая программирование, что в платформе уже реализованы вычисления неограниченной разрядности? Что сколько угодно знаков факториала получается и так обычным умножением. То есть вместо

    Использовано разбиение строкового представления числа на части по N цифр

    в платформе использовано разбиение представление числа на части по 9 разрядов! По этой ссылке есть более подробное обсуждение:

    http://forum.infostart.ru/forum24/topic122109/message1275993/#message1275993

    Почему именно 9 разрядов? — Думаю, потому, что 32-битное целое как раз укладывается в это представление и элементарные операции над частями по 9 десятичных цифр можно делать как операции над 32-битными целыми.

    Reply
  7. catsam

    (6) ildarovich,

    Несомненно, автор знал. Как следует из (4).

    И несомненно, 1С прекрасно обрабатывает «вычисления неограниченной разрядности». Вот только при выводе результата, он, к сожалению, как это ни печально, обрезается.

    Так что теории — это, конечно, хорошо, но попробовать на практике, наверное, все же стоило бы, прежде чем прозрачно намекать на бесполезность кода. 😉

    И да — этот код написан и выложен сюда в образовательных целях. =) Несомненно, расчет факториала в бизнесе нафиг никому не нужен. И конечно, есть множество библиотек, которые считают его на порядки быстрее, если он, конечно, вдруг понадобился. Но вот только использование библиотек никак не поможет в, как Вы правильно выразились, «саморазвитии».

    С уважением.

    Reply
  8. ildarovich

    (7) а почему не пробовали просто вывод организовать, а сразу стали всю длинную арифметику делать? Вывод по 9 цифр, например? Если сами расчеты делаются, результат хранится, а проблема просто в выводе? Не было бы это проще?

    Reply
  9. catsam

    (8) Ну, во-первых, насколько проблема именно в выводе, а не в _хранении_ итогового значения «внутрях» 1С, я не проверял. И, честно говоря, не собираюсь. Ибо это проблема не моя, а 1С.

    А во-вторых, как я уже говорил в (7), «этот код написан и выложен сюда в образовательных целях». Знаете, есть такая штука — образование? Вот это оно и есть. Неофит придет сюда, взглянет, код почитает и, есть вероятность, где-то и в чем-то продвинется. Такие вот дела…

    Лично мне задача показалась прикольной. Стоящей того, чтобы реализовать именно её, а не «вытаскивание из недр 1С результата вычислений, который она самостоятельно отобразить не в состоянии». =)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *