2014-12-05 1 views
1

Я хочу прочитать файл holiday.csv и сравнить даты в этом файле с сегодняшней датой, чтобы определить, является ли сегодня праздником.Прочтите csv файл и сравните с сегодняшней датой

Вот то, что я до сих пор ...

файл = holiday.csv

дата, название праздника, США отдыха, а именно:

Dec 25,Christmas,US Holiday 
Jan 1,New Year,US Holiday 
Jan 19,Martin Luther King,US Holiday 

Псевдо код:

package require csv 
proc mktopen {min hour day month weekday} { 
global stockchan 
    if {get date's from holiday.csv and compare to today's date if TRUE then} { 
     putserv "privmsg #channel :\0030,4 09:30ET\0030,12 (((US MARKET CLOSED - US HOLIDAY))) \017" 
    } else { 
     putserv "privmsg #channel :\0030,4 09:30ET\0030,12 (((US MARKET OPEN))) \017" 
    } 

} 
+0

Можете ли вы опубликовать некоторые строки из файла «holiday.csv»? Не все из них, но говорят 3-4. – Paul

+0

[This] (http://wiki.tcl.tk/3189) может быть вам полезен. – Jerry

+0

это похоже на смесь Tcl и псевдокода для меня. –

ответ

1

Сначала я получил все даты из файла csv, а затем сравнил его с датой прямо сейчас.

Однако, я не использую пакет CSV, что много, и я не заметил команду взять только один столбец из таблицы в формате CSV, поэтому я представлю решение без использования пакета CSV:

# Open the file for reading 
set holiday_file [open "holiday.csv" r] 

# Get all the holidays in a list called $holidays 
set holidays [list] 
while {[gets $holiday_file line] != -1} { 
    lappend holidays [lindex [split $line ,] 0] 
} 

# Get today's date in the required format 
set today [clock format [clock scan now] -format "%b %d"] 
lset today 1 [format %d [lindex $today 1]] 

# Compare with today's date 
if {[lsearch -exact $holidays $today] > -1} { 
    putserv "privmsg #channel :\0030,4 09:30ET\0030,12 (((US MARKET CLOSED - US HOLIDAY))) \017" 
} else { 
    putserv "privmsg #channel :\0030,4 09:30ET\0030,12 (((US MARKET OPEN))) \017" 
} 
+0

отлично работает ... большое спасибо – user2757400

+0

@ user2757400 Awesome, не стесняйтесь отмечать ответ как принятый, и ваша проблема решена в одно и то же время :) – Jerry

+0

Я бы использовал пакет 'csv' в tcllib, который работает хорошо с пакетом 'struct :: matrix'. Это будет иметь преимущество правильной обработки даже более опасных случаев кражи, таких как полевые или записывающие разделители в содержимом ячейки. Или, в противном случае, по крайней мере, меньше кода для написания и тестирования. ;-) –

0

Csv - сложный формат, и, как правило, нецелесообразно считывать данные csv с неполным синтаксическим анализатором. Конечно, это никогда никого не мешало делать именно так.

Если кто-то хочет сделать это в книге, тем не менее, заклинание происходит так.

package require csv 
package require struct::matrix 

Создать структуру матрицы данных, которая будет содержать данные из файла CSV и позволит нам работать с ним:

::struct::matrix m 

m теперь команда в текущем пространстве имен (вы можете добавить пространства имен на имя, чтобы создать его в другом пространстве имен). Как только вы закончите с матрицей, вы должны позвонить m destroy.

Вы также можете позволить имя модуля вашей команды матрицы и использовать его через переменную:

set m [::struct::matrix] 

Теперь, когда у вас есть матрица, вы можете загрузить содержимое файла CSV в него:

set ch [open holiday.csv] 
::csv::read2matrix $ch m , auto 
chan close $ch 

(Вы можете проверить это с m serialize (я добавил некоторые разрывы строк для удобства чтения) :)

3 3 { 
    {{Dec 25} Christmas {US Holiday }} 
    {{Jan 1} {New Year} {US Holiday }} 
    {{Jan 19} {Martin Luther King} {US Holiday}} 
} 

Для поиска заданной даты:

proc findDate date { 
    m search column 0 $date 
} 

Для поиска заданной строки в третьей колонке:

proc findStr str { 
    m search -glob column 2 $str* 
} 

(Поскольку некоторые из значений в столбце имеют нежелательные конечные пробела, нам нужно для поиска по string match правилам (-glob) вместо точного совпадения по умолчанию.)

Обе эти команды возвращают список ячеек, с которыми столкнулся поиск. Ячейки обозначаются парой столбцов/строк, например. {0 2} для матча в первой колонке, третьей строке.

Если мы просто хотим, чтобы выяснить, происходит ли данная дата в файле, этот предикат будет делать:

proc hasDate date { 
    expr {[llength [findDate $date]] > 0} 
} 

Но если мы хотим быть уверены, что строка дата была на самом деле содержит США праздник, нам нужно также проверить третий столбец. Есть много способов сделать это. Для одного из них, я в первую очередь необходимо вспомогательную функцию, чтобы преобразовать список ячеек дескрипторов к списку номеров строк:

proc getRowNums cells { 
    lmap cell $cells {lindex $cell 1} 
} 

Теперь я могу проверить даты и строки, как это:

proc hasDateAndString {date str} { 
    set r1 [getRowNums [findDate $date]] 
    set r2 [getRowNums [findStr $str]] 
    # do any rows overlap? 
    foreach r $r1 { 
     if {$r in $r2} { 
      return true 
     } 
    } 
    return false 
} 

Это работает, проверяя, имеют ли два списка строк какие-либо значения. Если они этого не сделают, дата не обозначает праздник в США.

Другим способ обхода матрицы по строкам и проверить соответствующие элементы в каждой строке:

proc hasDateAndString {date str} { 
    for {set row 0} {$row < [m rows]} {incr row} { 
     lassign [m get row $row] dateVal - strVal 
     if {$date eq $dateVal && [string match $str* $strVal]} { 
      return true 
     } 
    } 
    return false 
} 

Для каждой строки я смотрю, я извлекаю список значений с помощью m get row $row и lassign этих значений в переменных что я могу проверить.

Примечание: struct::matrix не очень хорошо работать. Люди говорят, что это медленно, и что еще хуже, это не очень хорошо скрывает детали низкого уровня. В некоторых случаях это less работать, чтобы читать файл csv с использованием обычного ввода/вывода Tcl, использовать ::csv::split, чтобы получить поля из каждой строки и записать их после использования ::csv::join, чтобы снова преобразовать их в строки csv.

Документация: chan, csv, expr, for, foreach, if, lassign, llength, lmap, open, package, proc, return, set, string, struct::matrix

lmap replacement for Tcl 8.4 and 8.5

 Смежные вопросы

  • Нет связанных вопросов^_^