, если кадр Data выглядит так:
group name count
fruit apple 90
fruit banana 150
fruit orange 130
vegetable broccoli 80
vegetable kale 70
vegetable lettuce 125
и OUTPUT могут быть как
group name count
0 fruit apple 90
1 fruit banana 150
2 fruit orange 130
, если вы используете логический оператор np.logical_not
df[np.logical_not(df['group'] == 'vegetable')]
подробнее о
https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html
другие логические операторы
Вы можете запустить perl cgi-script в терминале, используя следующую команду
$ perl filename.cgi
. Он интерпретирует код и предоставляет результат с кодом HTML. Он сообщит об ошибке, если таковой имеется.
perl -c filename
будет действительно проверять только синтаксис. Но perl filename
выводит вывод HTML. Это не гарантирует, что не будет ошибки 500 CGI, но это хороший первый тест.
– Nagev
18 May 2018 в 14:46
Я думаю, что CGI :: Debug стоит упомянуть.
Вероятно, стоит также упомянуть, что Perl всегда расскажет вам, в какой строке возникает ошибка при выполнении сценария Perl из командной строки. (Например, сеанс SSH)
Я обычно делаю это, если все остальное не работает. Я буду использовать SSH на сервере и вручную выполнить скрипт Perl. Например:
% perl myscript.cgi
Если возникла проблема, Perl расскажет вам об этом. Этот метод отладки устраняет любые проблемы с разрешением файла или проблемы с веб-браузером или веб-сервером.
Интересно, почему никто не упомянул вариант PERLDB_OPTS
, названный RemotePort
; хотя, по общему признанию, в Интернете мало рабочих примеров (RemotePort
даже не упоминается в perldebug ) - и для меня было довольно проблематично придумать это, но здесь оно (это пример Linux).
Чтобы сделать правильный пример, сначала мне понадобилось что-то, что могло бы сделать очень простое моделирование веб-сервера CGI, желательно через одну командную строку. После нахождения Простой веб-сервер командной строки для запуска cgis. (perlmonks.org) , я нашел для этого теста IO :: All - A Tiny Web Server .
Здесь я буду работать в каталог /tmp
; сценарий CGI будет /tmp/test.pl
(см. ниже). Обратите внимание, что сервер IO::All
будет обслуживать только исполняемые файлы в том же каталоге, что и CGI, поэтому здесь требуется chmod +x test.pl
. Итак, чтобы выполнить обычный тестовый прогон CGI, я меняю каталог на /tmp
в терминале и запускаю там один веб-сервер:
$ cd /tmp
$ perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'
Команда webserver будет блокироваться в терминале, и в противном случае запустит веб-сервер локально (на 127.0.0.1 или localhost
) - впоследствии я могу перейти в веб-браузер и запросить этот адрес:
http://127.0.0.1:8080/test.pl
... и я должен обратите внимание на print
s, сделанные с помощью test.pl
, загружаемых - и показаны - в веб-браузере.
Теперь, чтобы отладить этот скрипт с RemotePort
, сначала нам понадобится слушателя в сети, через который мы будем взаимодействовать с отладчиком Perl; мы можем использовать инструмент командной строки netcat
(nc
, увиденный здесь: Perl 如何 удаленная отладка? ). Итак, сначала запустите прослушиватель netcat
в одном терминале, где он будет блокировать и ждать подключения на порту 7234 (который будет нашим портом отладки):
$ nc -l 7234
Затем нам нужно perl
для запуска в режиме отладки с RemotePort
, когда test.pl
был вызван (даже в режиме CGI, через сервер). Это можно сделать в Linux, используя следующий сценарий «shebang wrapper», который также должен находиться в /tmp
, а должен быть выполнен :
cd /tmp
cat > perldbgcall.sh <<'EOF'
#!/bin/bash
PERLDB_OPTS="RemotePort=localhost:7234" perl -d -e "do '$@'"
EOF
chmod +x perldbgcall.sh
Это своего рода сложная вещь - см. Сценарий оболочки - Как я могу использовать переменные среды в моем shebang? - Unix & amp; Linux Stack Exchange . Но трюк здесь, кажется, не , чтобы развить интерпретатор perl
, который обрабатывает test.pl
- поэтому, как только мы его ударим, мы не exec
, но вместо этого мы вызываем perl
«прямо» и в основном «источник» нашего скрипта test.pl
с использованием do
(см. . Как запустить скрипт Perl из скрипта Perl? ).
Теперь что у нас есть perldbgcall.sh
в /tmp
- мы можем изменить файл test.pl
, так что он ссылается на этот исполняемый файл на своей строке shebang (вместо обычного интерпретатора Perl) - здесь /tmp/test.pl
изменено таким образом:
#!./perldbgcall.sh
# this is test.pl
use 5.10.1;
use warnings;
use strict;
my $b = '1';
my $a = sub { "hello $b there" };
$b = '2';
print "YEAH " . $a->() . " CMON\n";
$b = '3';
print "CMON " . &$a . " YEAH\n";
$DB::single=1; # BREAKPOINT
$b = '4';
print "STEP " . &$a . " NOW\n";
$b = '5';
print "STEP " . &$a . " AGAIN\n";
Теперь оба test.pl
и его новый обработчик shebang, perldbgcall.sh
, находятся в /tmp
; и мы nc
слушаем отладочные соединения на порту 7234 - поэтому мы можем, наконец, открыть другое окно терминала, сменить каталог на /tmp
и запустить веб-сервер с одним слоем (который будет прослушивать веб-соединения на порту 8080):
cd /tmp
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'
После этого мы можем перейти в наш веб-браузер и запросить тот же адрес, http://127.0.0.1:8080/test.pl
. Однако теперь, когда веб-сервер пытается выполнить скрипт, он сделает это через perldbgcall.sh
shebang - который запустит perl
в режиме удаленного отладчика. Таким образом, выполнение скрипта приостанавливается - и поэтому веб-браузер блокируется, ожидая данных. Теперь мы можем переключиться на терминал netcat
, и мы должны увидеть знакомый текст отладчика Perl, однако вывести его через nc
:
$ nc -l 7234
Loading DB routines from perl5db.pl version 1.32
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:1): do './test.pl'
DB<1> r
main::(./test.pl:29): $b = '4';
DB<1>
. Как показывает фрагмент, теперь мы в основном используем nc
как «терминал», поэтому мы можем ввести r
(и Enter) для «run» - и скрипт будет запускаться с помощью инструкции breakpoint (см. также В perl, в чем разница между $ DB: : single = 1 и 2? ), прежде чем снова остановиться (обратите внимание, что в этот момент браузер все равно заблокируется).
Итак, теперь мы можем, скажем, пройти через остальные test.pl
через терминал nc
:
....
main::(./test.pl:29): $b = '4';
DB<1> n
main::(./test.pl:30): print "STEP " . &$a . " NOW\n";
DB<1> n
main::(./test.pl:31): $b = '5';
DB<1> n
main::(./test.pl:32): print "STEP " . &$a . " AGAIN\n";
DB<1> n
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
DB<1>
... однако, также в этот момент браузер блокирует и ждет данных. Только после выхода из отладчика с q
:
DB<1> q
$
... блокирует блокировку браузера и, наконец, отображает (полный) вывод test.pl
:
YEAH hello 2 there CMON
CMON hello 3 there YEAH
STEP hello 4 there NOW
STEP hello 5 there AGAIN
Конечно, такой отладочный процесс можно сделать даже без запуска веб-сервера, однако, в этом случае, мы не трогаем веб-сервер; мы запускаем выполнение «изначально» (для CGI) из веб-браузера - и единственным изменением, необходимым для самого скрипта CGI, является изменение shebang (и, конечно же, наличие скрипта оболочки shebang в качестве исполняемого файла в том же директория).
Ну, надеюсь, это поможет кому-то - я бы наверняка любил бы наткнуться на это, вместо того, чтобы писать сам :)
Cheers!
Используете ли вы обработчик ошибок во время отладки?
die
операторы и другие фатальные ошибки времени выполнения и времени компиляции печатаются на STDERR
, которые трудно найти и могут быть объединены с сообщениями с других веб-страниц вашего сайта. Хотя вы отлаживаете свой сценарий, неплохо было бы получить сообщения о фатальных ошибках для отображения в вашем браузере.
Один из способов сделать это - вызвать
use CGI::Carp qw(fatalsToBrowser);
в верхней части вашего скрипта. Этот вызов установит обработчик $SIG{__DIE__}
(см. perlvar ) отображает фатальные ошибки в вашем браузере, добавляя при необходимости допустимый заголовок. Другой трюк отладки CGI, который я использовал до того, как я когда-либо слышал о CGI::Carp
, состоял в том, чтобы использовать eval
с возможностями DATA
и __END__
в скрипте для обнаружения ошибок времени компиляции:
#!/usr/bin/perl
eval join'', <DATA>;
if ($@) { print "Content-type: text/plain:\n\nError in the script:\n$@\n; }
__DATA__
# ... actual CGI script starts here
Этот более подробный метод имеет небольшое преимущество перед CGI::Carp
в том, что он будет ловить больше ошибок времени компиляции.
Обновление: я никогда не использовал его, но он выглядит как CGI::Debug
, как предложил Mikael S, также является очень полезным и настраиваемым инструментом для этой цели.
<DATA>
- волшебный дескриптор файла, который читает текущий скрипт, начиная с __END__
. Join предоставляет контекст списка, поэтому & lt; fh & gt; возвращает массив, по одной строке на элемент. Затем объединение объединяет его (соединяет его с ''). Наконец, eval.
– derobert
9 September 2010 в 20:04
eval join(q{}, <DATA>);
– derobert
9 September 2010 в 20:06
Честно говоря, вы можете сделать все самое интересное над этим сообщением. ALTHOUGH, самое простое и наиболее проактивное решение, которое я нашел, это просто «распечатать его».
В примере: (Обычный код)
`$somecommand`;
Чтобы узнать, делает ли он то, что я действительно хочу, чтобы он делал: (Устранение неполадок)
print "$somecommand";
Для меня я использую log4perl . Это очень полезно и легко.
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init( { level => $DEBUG, file => ">>d:\\tokyo.log" } );
my $logger = Log::Log4perl::get_logger();
$logger->debug("your log message");