Re: [racket-users] IO in racket is painful

2017-07-22 Thread Matthew Butterick

> On Jul 22, 2017, at 12:30 PM, David Storrs  wrote:
> 
> One thing that would solve a lot of this issue would be if the pregexp syntax 
> added support for named captures as in Perl and the PCRE library that exports 
> them. 
> 
> Alternatively, if 'match' made the results of a successful regexp test 
> available to the bodies on the RHS then you could do the same thing by 
> accessing the result list.  Perhaps if match would allow the RHS to be a 
> function?



This could also be a light syntactic abstraction over `cond`:

#lang at-exp racket

(define-syntax (regexp-case stx)
  (syntax-case stx (=> else)
[(_ STR [PAT => PROC] ... [else . ELSE-BODY])
 #'(cond
 [(regexp-match PAT STR) => PROC] ...
 [else . ELSE-BODY])]
[(_ STR [PAT => PROC] ...) #'(regexp-case STR [PAT => PROC] ... [else 
#f])]))

(define str "[04, foo, 03.5]")
(define pat @(pregexp @~a{\[(\d+),\s*(\w+),\s*([.\d]+)}))
(regexp-case str
 [pat => (λ (res) (match-let ([(list _ item-num name price) res])
(println (~a "item name: " name ", number: " 
item-num ", price: $" price])

(regexp-case "foobar"
 [#px"oo.+(.)" => (lambda (res) (println (~a "Regexp match results 
were: " res)))])

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-22 Thread David Storrs
Oh, cool.  I did not know about that.  Thanks, Jon.

On Sat, Jul 22, 2017 at 4:49 PM, Jon Zeppieri  wrote:

> On Sat, Jul 22, 2017 at 3:30 PM, David Storrs 
> wrote:
> >
> > Alternatively, if 'match' made the results of a successful regexp test
> > available to the bodies on the RHS then you could do the same thing by
> > accessing the result list.  Perhaps if match would allow the RHS to be a
> > function?
> >
> > (match "foo"
> >   [#px"oo.+(.)" (lambda (res) (println (~a "Regexp match results were: "
> > res)))])
> >
> > Output:
> > '("oobar" "r")
> >
>
> This, at least, already exists:
>
> (match "foobar"
>   [(pregexp #px"oo.+(.)" res)
>(println (~a "Regexp match results were: " res))])
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-22 Thread Jon Zeppieri
On Sat, Jul 22, 2017 at 3:30 PM, David Storrs  wrote:
>
> Alternatively, if 'match' made the results of a successful regexp test
> available to the bodies on the RHS then you could do the same thing by
> accessing the result list.  Perhaps if match would allow the RHS to be a
> function?
>
> (match "foo"
>   [#px"oo.+(.)" (lambda (res) (println (~a "Regexp match results were: "
> res)))])
>
> Output:
> '("oobar" "r")
>

This, at least, already exists:

(match "foobar"
  [(pregexp #px"oo.+(.)" res)
   (println (~a "Regexp match results were: " res))])

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-22 Thread David Storrs
One thing that would solve a lot of this issue would be if the pregexp
syntax added support for named captures as in Perl and the PCRE library
that exports them.  Something like this:

#lang at-exp racket

(define str "[04, foo, 03.5]")
(define pat @(pregexp
@~a{\[(?\d+),\s*(?\w+),\s*(?[.\d]+)}))

(match str
  [pat (println (~a "item name: " name ", number: " item-num ", price: $"
price))])

Alternatively, if 'match' made the results of a successful regexp test
available to the bodies on the RHS then you could do the same thing by
accessing the result list.  Perhaps if match would allow the RHS to be a
function?

(match "foo"
  [#px"oo.+(.)" (lambda (res) (println (~a "Regexp match results were: "
res)))])

Output:
'("oobar" "r")

On Fri, Jul 21, 2017 at 6:20 PM, Gustavo Massaccesi 
wrote:

> IIRC the previous discussion, one way to fix this problem is to make a
> package that can parse strings easily using a C like format, like the
> expected in the contests. Something like
>
> #lang racket
> (require compatibility/scanf)
>
> (let-values ([(x y) (scanf "%d %d" (read-line))])
>   (display (+ x y)))
>
> It's not very idiomatic, but it may be helpful for this particular use.
>
> IIRC another problem is that in the contest you are not allowed to
> install the packages you wish, you can only use the default
> installation. But I think that the idea is not to allow everything in
> the default installation.
>
>
> So my proposal is to add another installation mode for Racket
>
> * minimal: Only the core and some minimal packages
> * main: The normal set of packages, (only idiomatic) batteries included.
> * community (new): everything in the ring 1, including the kitchen
> sink. With a minimal curation and a minimal baseline of features (like
> no breaking the installation). (And a compatible license.) The
> packages may disappear/change/reappear from version to version. All
> the additional packages may be experimental/unstable/unsuported.
>
> Is this acceptable in a competition?
> Is this acceptable as another "official" Racket distribution?
>
> Gustavo
>
>
>
> On Fri, Jul 21, 2017 at 4:35 PM, Brian Mastenbrook
>  wrote:
> > On 07/21/2017 12:49 PM, Matthias Felleisen wrote:
> >>
> >>
> >>> On Jul 21, 2017, at 1:56 AM, Sorawee Porncharoenwase
> >>>  wrote:
> >>>
> >>> Sorry for reviving an old thread. As someone who did a lot of
> programming
> >>> competition in the past, I can totally see why IO in Racket is
> difficult. As
> >>> mark.engelberg said, the goal is to solve as many problems as possible.
> >>> After the competition is over, it's over. No one is going to care about
> >>> maintainability or good coding practice if it makes coding slower.
> >>
> >>
> >> Which is why I think programming competitions are a direct attempt to
> >> undermine computer science and computer-science education.
> >>
> >> Having said that, if you want to use Racket for competitions, you and
> Mark
> >> Engelberg should get together and produce a high-utility IO library. We
> can
> >> then include it in the distribution.
> >
> >
> > Just as a counterpoint, I have this kind of ad-hoc
> parse-this-produce-that
> > problem all the time in the "real" world. When the logic of the problem
> is
> > sufficiently complex I'll swallow the overhead of doing it in Racket, or
> > I'll use Perl to transform the input into something I can read in
> Racket. It
> > would be nice to have an I/O library that made it easy, but I don't have
> any
> > specific thoughts about how to do that.
> >
> > I don't think computer science education should ignore this kind of
> problem
> > though. It's very important to teach students how to solve problems
> > methodically with a design recipe, how to collaborate with others, and
> how
> > to reason about their programs. But it's also important that programmers
> > (and also or even especially those who don't program for a living) be
> > comfortable with using the machine to solve or automate the solution to
> > one-off problems that would otherwise require a lot of manual fiddling
> with
> > data. Being fluent with this kind of programing gives people the
> confidence
> > they need to solve smaller problems or explore potential solutions to
> large
> > problems in an unstructured manner before tackling the methodical,
> "right"
> > solution.
> >
> > --
> > Brian Mastenbrook
> > br...@mastenbrook.net
> > https://brian.mastenbrook.net/
> >
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to racket-users+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email 

Re: [racket-users] IO in racket is painful

2017-07-21 Thread Gustavo Massaccesi
IIRC the previous discussion, one way to fix this problem is to make a
package that can parse strings easily using a C like format, like the
expected in the contests. Something like

#lang racket
(require compatibility/scanf)

(let-values ([(x y) (scanf "%d %d" (read-line))])
  (display (+ x y)))

It's not very idiomatic, but it may be helpful for this particular use.

IIRC another problem is that in the contest you are not allowed to
install the packages you wish, you can only use the default
installation. But I think that the idea is not to allow everything in
the default installation.


So my proposal is to add another installation mode for Racket

* minimal: Only the core and some minimal packages
* main: The normal set of packages, (only idiomatic) batteries included.
* community (new): everything in the ring 1, including the kitchen
sink. With a minimal curation and a minimal baseline of features (like
no breaking the installation). (And a compatible license.) The
packages may disappear/change/reappear from version to version. All
the additional packages may be experimental/unstable/unsuported.

Is this acceptable in a competition?
Is this acceptable as another "official" Racket distribution?

Gustavo



On Fri, Jul 21, 2017 at 4:35 PM, Brian Mastenbrook
 wrote:
> On 07/21/2017 12:49 PM, Matthias Felleisen wrote:
>>
>>
>>> On Jul 21, 2017, at 1:56 AM, Sorawee Porncharoenwase
>>>  wrote:
>>>
>>> Sorry for reviving an old thread. As someone who did a lot of programming
>>> competition in the past, I can totally see why IO in Racket is difficult. As
>>> mark.engelberg said, the goal is to solve as many problems as possible.
>>> After the competition is over, it's over. No one is going to care about
>>> maintainability or good coding practice if it makes coding slower.
>>
>>
>> Which is why I think programming competitions are a direct attempt to
>> undermine computer science and computer-science education.
>>
>> Having said that, if you want to use Racket for competitions, you and Mark
>> Engelberg should get together and produce a high-utility IO library. We can
>> then include it in the distribution.
>
>
> Just as a counterpoint, I have this kind of ad-hoc parse-this-produce-that
> problem all the time in the "real" world. When the logic of the problem is
> sufficiently complex I'll swallow the overhead of doing it in Racket, or
> I'll use Perl to transform the input into something I can read in Racket. It
> would be nice to have an I/O library that made it easy, but I don't have any
> specific thoughts about how to do that.
>
> I don't think computer science education should ignore this kind of problem
> though. It's very important to teach students how to solve problems
> methodically with a design recipe, how to collaborate with others, and how
> to reason about their programs. But it's also important that programmers
> (and also or even especially those who don't program for a living) be
> comfortable with using the machine to solve or automate the solution to
> one-off problems that would otherwise require a lot of manual fiddling with
> data. Being fluent with this kind of programing gives people the confidence
> they need to solve smaller problems or explore potential solutions to large
> problems in an unstructured manner before tackling the methodical, "right"
> solution.
>
> --
> Brian Mastenbrook
> br...@mastenbrook.net
> https://brian.mastenbrook.net/
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-21 Thread Brian Mastenbrook

On 07/21/2017 12:49 PM, Matthias Felleisen wrote:



On Jul 21, 2017, at 1:56 AM, Sorawee Porncharoenwase 
 wrote:

Sorry for reviving an old thread. As someone who did a lot of programming 
competition in the past, I can totally see why IO in Racket is difficult. As 
mark.engelberg said, the goal is to solve as many problems as possible. After 
the competition is over, it's over. No one is going to care about 
maintainability or good coding practice if it makes coding slower.


Which is why I think programming competitions are a direct attempt to undermine 
computer science and computer-science education.

Having said that, if you want to use Racket for competitions, you and Mark 
Engelberg should get together and produce a high-utility IO library. We can 
then include it in the distribution.


Just as a counterpoint, I have this kind of ad-hoc 
parse-this-produce-that problem all the time in the "real" world. When 
the logic of the problem is sufficiently complex I'll swallow the 
overhead of doing it in Racket, or I'll use Perl to transform the input 
into something I can read in Racket. It would be nice to have an I/O 
library that made it easy, but I don't have any specific thoughts about 
how to do that.


I don't think computer science education should ignore this kind of 
problem though. It's very important to teach students how to solve 
problems methodically with a design recipe, how to collaborate with 
others, and how to reason about their programs. But it's also important 
that programmers (and also or even especially those who don't program 
for a living) be comfortable with using the machine to solve or automate 
the solution to one-off problems that would otherwise require a lot of 
manual fiddling with data. Being fluent with this kind of programing 
gives people the confidence they need to solve smaller problems or 
explore potential solutions to large problems in an unstructured manner 
before tackling the methodical, "right" solution.


--
Brian Mastenbrook
br...@mastenbrook.net
https://brian.mastenbrook.net/

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-21 Thread Neil Van Dyke
Racket's underlying I/O seems sophisticated to me, and contest-friendly 
parsing conveniences can be layered atop that.


IIRC, a long time ago, Olin Shivers made some parsing stuff for Scheme, 
which you might want to steal or at least look at.  I'm not sure where 
it all went, or who else was involved, but I'd start looking here:


https://scsh.net/docu/html/man-Z-H-7.html#node_chap_6
https://scsh.net/docu/html/man-Z-H-8.html#node_chap_7
https://scsh.net/docu/html/man-Z-H-9.html#node_chap_8

The Racket package catalog is also worth a look.  I mostly know my own 
old packages, so I'll mention a few parsing-related ones:


For the broad category of CSV format data files (in addition to lots of 
quoting and escaping conventions, can also handle inputs like ASCII 
tables with columns separated by vertical bars, for example):

http://www.neilvandyke.org/racket/csv-reading/

For JSON parsing, you probably want to use the core Racket JSON stuff, 
but at one point I accidentally made a folding JSON parser 
(unfortunately, not using `syntax-parse`) that might come in handy for 
big data:

http://www.neilvandyke.org/racket/json-parsing/

For HTML parsing and rewriting, an ancient Scheme library probably still 
works (but you'll want to get comfortable with SXML ahead of time, 
especially if you're new to old-school list processing):

http://www.neilvandyke.org/racket/html-parsing/
http://www.neilvandyke.org/racket/sxml-intro/

If a contest ever requires that your program modify its own source file, 
we got yo back:

http://www.neilvandyke.org/racket/progedit/

Aside on programming contests: I see them as a good *side* thing, kept 
in perspective.  It's an alternative way that some people get excited 
about programming and problem-solving, and then put in the work and 
learn things along the way.  Two provisos:


(1) We have to be aware that contests can be anti-engineering, and 
remember to also learn engineering.  Know when to be in contest mode, 
vs. normal engineering mode, vs. somewhat sloppier mode, vs. urgent yet 
it must work perfectly and resiliently the first time or the asteroid 
will destroy Earth engineering mode, vs. the asteroid mode plus it might 
also need keep deflecting asteroids for years after mode.


(2) Don't let the existence of programming contests discourage people 
from learning programming or other STEM stuff.  The contests are 
artificial, and only loosely related to programming/STEM goals. Some 
people have a big head start on being good at contests, but, if you want 
to do programming and other STEM stuff, you can get good at that without 
ever having to be good at contests, nor even try contests.  (Related: 
try to find and remember a balance between humility and confidence -- in 
school, immediately post-school, and later.  If we're always thinking 
that we have more to learn, but that we do know some things, and can 
build upon that to help tackle goals that seem hard, I think that's a 
good starting point for finding this balance.)


--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-21 Thread Matthias Felleisen

> On Jul 21, 2017, at 1:56 AM, Sorawee Porncharoenwase 
>  wrote:
> 
> Sorry for reviving an old thread. As someone who did a lot of programming 
> competition in the past, I can totally see why IO in Racket is difficult. As 
> mark.engelberg said, the goal is to solve as many problems as possible. After 
> the competition is over, it's over. No one is going to care about 
> maintainability or good coding practice if it makes coding slower. 


Which is why I think programming competitions are a direct attempt to undermine 
computer science and computer-science education. 

Having said that, if you want to use Racket for competitions, you and Mark 
Engelberg should get together and produce a high-utility IO library. We can 
then include it in the distribution. 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2017-07-20 Thread Sorawee Porncharoenwase
Sorry for reviving an old thread. As someone who did a lot of programming 
competition in the past, I can totally see why IO in Racket is difficult. As 
mark.engelberg said, the goal is to solve as many problems as possible. After 
the competition is over, it's over. No one is going to care about 
maintainability or good coding practice if it makes coding slower. For this 
reason, I wouldn't use parsack if possible. While elegant, there's too much to 
write which is a waste of time.

Luckily, major programming competitions (say, Facebook Hacker Cup, Google Code 
Jam, early IOI, ACM-ICPC, etc.) usually have simple input format. Data are 
usually separated by spaces. Rarely spaces matter. rom gcb says that the input 
is:

  3
  [04, foo, 03.5]
  [05, bar, 04.6]
  [06, fun, 05.7]

but in these competitions, the input is more likely to be:

  3
  04 foo 03.5
  05 bar 04.6
  06 fun 05.7

What really gets in the way is that strings in the input could be something 
that Racket's (read) doesn't recognize. As an example, a string might be #asd. 
This would cause (read) to error "read: bad syntax `#a'".

Indeed, using (read-line) along with regex would solve the problem. The 
downside is that it requires a lot of writing and is heavily task-dependent. 
What I want is a uniform way to extract data easily like scanf.

I write the following module for this purpose. It's a lot of code, so it would 
be useless in closed competitions like ACM-ICPC. However, for online 
competitions like FB Hacker Cup, I find it pretty useful.


#lang racket

(provide (all-defined-out))

(define read-next
  (let ([buffer #f])
(lambda (#:to-eol [to-eol #f])
  (define (more!) (set! buffer (read-line)) (read-next #:to-eol to-eol))
  (match buffer
[(? string?)
 (cond
   [to-eol (let ([ret buffer]) (set! buffer #f) ret)]
   [else
(set! buffer (string-trim buffer #:right? #f))
(match (regexp-match #px"\\S+" buffer)
  [(list ret) (set! buffer (regexp-replace #px"^\\S+" buffer "")) 
ret]
  [#f (more!)])])]
[_ (more!)]

(define (%list n typ) (thunk (for/list ([_ n]) (typ
(define (%gets) (read-next #:to-eol #t))
(define (%num) (string->number (read-next)))
(define (%str) (read-next))
(define-syntax-rule (scan [v m] ...) (begin (define v (m)) ...))

(module+ test
  (require rackunit)
  (parameterize
  ([current-input-port
(open-input-string
 (string-append "2  3  \n"
"123\n"
"   4   5   6\n"
"   \n"
"  \n"
" \n"
"\n"
" '\"has-quotes\"' blah blah "))])
(scan [n %num]
  [m %num]
  [matrix (%list n (%list m %num))]
  [trailing-spaces %gets]
  [str-with-quotes %str]
  [line-with-space %gets])
(check-equal? n 2)
(check-equal? m 3)
(check-equal? matrix (list (list 1 2 3) (list 4 5 6)))
(check-equal? trailing-spaces "")
(check-equal? str-with-quotes "'\"has-quotes\"'")
(check-equal? line-with-space " blah blah ")))



For example, https://code.google.com/codejam/contest/6254486/dashboard#s=p1 can 
be solved as follows:

(scan [n %num])
(for ([i n])
  (scan [s %str])
  (define simp (regexp-replaces s '([#px"\\++" "+"] [#px"\\-+" "-"])))
  (define len (string-length simp))
  (printf "Case #~a: ~a\n"
  (add1 i)
  (match (list (string-ref simp 0) (even? len))
[(or (list #\+ #t) (list #\- #f)) len]
[(or (list #\+ #f) (list #\- #t)) (sub1 len)])))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-31 Thread m . eckenbach
Isn't it true that the scanf format string is just a poor man's regular 
expression pattern (i.e. just character classes) that however also allows you 
to specify how to convert matches? It may be a succinct notation, but it is 
also misleading (for example, a single space in the format string matches any 
amount of whitespace in the input!?). And it is inflexible: What if I create a 
new data structure? The implementation will not provide for a conversion.

I don't think there is need for a c-like scanf in racket. Why not just use 
regexp-match and do something like this:

(define (regexp-match-format pattern input . conversion-procs)
  (define reports (rest (regexp-match pattern input)))
  (for/list ([r reports]
 [c conversion-procs])
(c r)))

And use it like this:

(regexp-match-format #rx"\\[(.+), *(.+), *(.+)\\]"
 (read-line)
 string->number
 values
 string->number)





Am Mittwoch, 23. März 2016 05:06:18 UTC+1 schrieb Alexis King:
> Honestly, judging from the responses in this thread, it would seem there
> may be a hole in Racket’s toolbox. Nothing I’ve seen so far is
> particularly stellar, especially since this is a problem that does not
> seem like it should be hard.
> 
> It may be overkill for this use case, but I would probably use the
> parsack package, since I think its interface is pretty intuitive.
> However, it would be nice to have some sort of inverse to printf that
> parses values given a template string. Racket has a very good set of
> tools for formatting text, but it seems that doing the inverse is much
> harder, which seems to be against Racket’s “batteries included”
> philosophy.
> 
> Would anyone object to a scanf-like function in Racket itself? The
> obvious point of difficulty is how to handle errors, given that parsing
> can fail but printing cannot. Should it throw an exception, or should it
> return #f? I’m not sure there is great precedent set here, though
> throwing seems to be the Racket way in other places.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Mark Engelberg
On Tue, Mar 22, 2016 at 9:20 PM, Stephen Chang  wrote:

> :) I had started writing up a parsack example, and I was all set to
> admonish the OP for not creating a parser when you want a parser but
> then I saw it was for a programming contest where I guess this sort of
> scanf/regexp hackery is ok?
>

Generally the purpose of these sorts of programming contests is to solve as
many programming problems as you can in the span of, say, 3 hours.  So it
is all about writing code as fast as you can, nothing else counts.

One of the ground rules in the programming contests in my area is that you
cannot use any libraries that don't come with the language.  So if it comes
with the Racket distribution, that's fine.  But you can't pre-code up a
library of functions you would like to use, and you can't download and
install a package from Planet or Github.  Does Parsack come with Racket?
Is Parsack the quickest way (in terms of time to write the code) to dice
the file into a list of datasets?  Those are the questions that matter here.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Stephen Chang
> It may be overkill for this use case, but I would probably use the
> parsack package, since I think its interface is pretty intuitive.

:) I had started writing up a parsack example, and I was all set to
admonish the OP for not creating a parser when you want a parser but
then I saw it was for a programming contest where I guess this sort of
scanf/regexp hackery is ok?

> Should it throw an exception, or should it
> return #f? I’m not sure there is great precedent set here, though
> throwing seems to be the Racket way in other places.

printf throws an exception when there's a type mismatch, eg (printf "~b" "1")

(thanks for the example Ben)


>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Alexis King
Honestly, judging from the responses in this thread, it would seem there
may be a hole in Racket’s toolbox. Nothing I’ve seen so far is
particularly stellar, especially since this is a problem that does not
seem like it should be hard.

It may be overkill for this use case, but I would probably use the
parsack package, since I think its interface is pretty intuitive.
However, it would be nice to have some sort of inverse to printf that
parses values given a template string. Racket has a very good set of
tools for formatting text, but it seems that doing the inverse is much
harder, which seems to be against Racket’s “batteries included”
philosophy.

Would anyone object to a scanf-like function in Racket itself? The
obvious point of difficulty is how to handle errors, given that parsing
can fail but printing cannot. Should it throw an exception, or should it
return #f? I’m not sure there is great precedent set here, though
throwing seems to be the Racket way in other places.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Mark Engelberg
Hi, I have coached several teams on using Racket in programming contests.

In our local contests, the most common input format is to have one line per
dataset, and each dataset is typically several pieces of data separated by
spaces.  For this common input format, the 2htdp/batch-io teachpack is the
most convenient tool.

Here is a document I give to beginner students about how to use the
teachpack for the common case:
https://docs.google.com/document/d/1rJ9psWwB6qbYrYSKriQi15IpgN1qjQSxE4riAPHhQE8/edit?usp=sharing

But the advanced students sometimes run into files like the one you
describe, where the input has a somewhat different.  I teach the students
to build up a little toolkit of useful functions that they can write very
quickly once at the beginning of the contest -- functions that are useful
for "slicing and dicing" any file into a list of datasets.

Here are three such functions, that come in handy:

#lang racket
(require srfi/1)

; f->l stands for file->lines. We use the shorter name for less typing in a
contest, and to avoid conflict with built-in file->lines
; A hard lesson we learned is that in contests, the input files aren't
always "clean".  Sometimes there are stray spaces at the
; front or end of certain lines, or extra blank lines at the end of the
file.  This version of file->lines sanitizes the input.
(define (f->l file)
  (reverse (drop-while (curry equal? "") (reverse (map string-trim
(file->lines file))

; convert takes a string as an input and converts it to a number if it is a
number, otherwise, leaves it alone
(define (convert s)
  (if (string->number s)(string->number s) s))

; string-parse takes a string which is strings and/or numbers separated by
spaces, and returns a list of those elements
; So (string-parse "hello 1 2.0 world") returns (list "hello" 1 2.0 "world")
(define (string-parse s)
  (map convert (string-split s)))


Once these three functions are written (once at the beginning of the
contest), you can tackle a problem like yours as follows:

; Now we solve the contest problem

; We don't need the initial number of lines, because Racket is awesome.
; Let's take a moment to pity the students who use languages that force
them to read
; the data into a fixed-length array.

; Now, let's do it our way, and drop the number of lines with a simple call
to rest.

(define lines (rest (f->l "C:/temp/infile.dat")))

; We can put a line into a format consumable by string-parse by getting rid
of brackets and commas
; regexp-replace* is a very useful function to remember
; Make a habit out of using #px rather than #rx, as it supports some
additional features that can be useful,
; and it's easier to just always use #px instead of trying to recall which
features require which regexp type.

(define datasets (for*/list ([line lines]) (string-parse (regexp-replace*
#px"\\[|\\]|," line ""

; So that's all it took with our "library" of three functions in place.
; It just took two lines to massage the input file into a list of datasets.
; Now we implement the logic of processing a given dataset.
; If you know match, you might want to write it this way:

(define (process-dataset ds)
  (match ds
[`(,a ,b ,c)
 (printf "[~a, ~a, ~a]\n"
  (~a a #:width 2 #:align 'right #:pad-string "0
  b
  (~r c #:min-width 4 #:precision 1 #:pad-string "0"))]))

(for ([dataset datasets]) (process-dataset dataset))

; Alternatively, if you don't know match, you can write it as follows,
taking advantage of apply.

(define (process-dataset a b c)
  (printf "[~a, ~a, ~a]\n"
  (~a a #:width 2 #:align 'right #:pad-string "0")
  b
  (~r c #:min-width 4 #:precision 1 #:pad-string "0")))

(for ([dataset datasets]) (apply process-dataset dataset))


With most problems, it only takes a few lines like this to manipulate the
input file into a list of datasets, so my students have done well without a
scanf function.  Not that it wouldn't hurt to have it in specific
situations, but it's usually not necessary.

Good luck in the contest!

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread WarGrey Gyoudmon Ju
On Wed, Mar 23, 2016 at 8:26 AM, WarGrey Gyoudmon Ju 
wrote:

> In Racket, (read) and (write) know all the builtin datatypes
> 
>  which
> are already structured more than a stream of bytes (like in C).
> Thus, you don't need scanf to tell Racket what is the type of the next
> token.
>
> That *is* painful in a situation like coding challenges since the input
> format is language independent (however actually it's the C style).
> Of course this kind of situation also has its own fixed format, you can
> define your own read tables
>  :
> 1. the "," is special in Racket, you need to drop off them first;  
> (with-input-from-string
> "[04 foo 03.5]" read) gives you '(4 foo 3.5) directly.
> 2. Symbols are internal Strings, you need (symbol->string) to covent them
> into normal Strings (Yes, sometimes, I think if there are string-like or
> bytes-like APIs that work on symbols directly).
>
>
Sorry, please forget the Read Table, it makes things more complex here.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread WarGrey Gyoudmon Ju
In Racket, (read) and (write) know all the builtin datatypes

which
are already structured more than a stream of bytes (like in C).
Thus, you don't need scanf to tell Racket what is the type of the next
token.

That *is* painful in a situation like coding challenges since the input
format is language independent (however actually it's the C style).
Of course this kind of situation also has its own fixed format, you can
define your own read tables
 :
1. the "," is special in Racket, you need to drop off them first;
(with-input-from-string
"[04 foo 03.5]" read) gives you '(4 foo 3.5) directly.
2. Symbols are internal Strings, you need (symbol->string) to covent them
into normal Strings (Yes, sometimes, I think if there are string-like or
bytes-like APIs that work on symbols directly).


On Wed, Mar 23, 2016 at 4:33 AM, rom cgb  wrote:

> Hi,
>
> I recently started using Racket and i couldn't find a good alternative to
> C's scanf/printf in the racket standard library. When doing programming
> challenges, you often need to comply to a specific input/ouput thus having
> something like scanf for string to values and printf for values to string
> is comfy.
>
> For example, let's say a challenge where you simply have to output the
> input but you need to translate the strings input into values and then
> those values back to strings.
>
> The given input(and excepted ouput) is
>
>   3
>   [04, foo, 03.5]
>   [05, bar, 04.6]
>   [06, fun, 05.7]
>
> In C, you would simply do
>
>   #include 
>
>   int main(void)
>   {
>   int n;
>
>   // Read number of rows
>   scanf("%d\n", );
>
>   // Output number of rows
>   printf("%d\n", n);
>
>   // Process rows
>   for (unsigned int i; i < n; ++i)
>   {
>   int a;
>   char b[20];
>   float c;
>
>   // Read row
>   scanf("[%d, %[^,], %f]\n", , b, );
>
>   // Output row
>   printf("[%02d, %s, %04.1f]\n", a, b, c);
>   }
>   }
>
> Now, for a solution in Racket, You first have to read the first line and
> convert it into a number.
>
>   (define rows (string->number (read-line)))
>
> Then, for all rows, read and split the string. The best that i have found
> to do that is using regular expressions.
>
>   (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))
>
> Then you have to manually convert the substrings into values
>
>   (define a (string->number (second split-row)))
>   (define b (third split-row))
>   (define c (string->number (fourth split-row)))
>
> Then you have to manually convert the values back into strings
>
>   (printf "[~a, ~a, ~a]\n"
>   (~a a #:width 2 #:align 'right #:pad-string "0")
>   b
>   (~r c #:min-width 4 #:precision 1 #:pad-string "0")))
>
> This is way more tedious than with the classical input/output format,
> especially when you are doing coding challenges.
>
> Final Racket solution:
>
>   #lang racket
>
>   (define rows (string->number (read-line)))
>
>   (for ([in-range rows])
> (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]"
> (read-line)))
>
> (define a (string->number (second split-row)))
> (define b (third split-row))
> (define c (string->number (fourth split-row)))
>
> (printf "[~a, ~a, ~a]\n"
> (~a a #:width 2 #:align 'right #:pad-string "0")
> b
> (~r c #:min-width 4 #:precision 1 #:pad-string "0")))
>
>
> Having something like (not necessary the same specifiers as with printf)
>
>   (string-scan "[%d, %s, %f]" "[45, foo, 10.9]") -> '(45 "foo" 10.9)
>
> and a proper output formatter would be comfy.
>
> Are racket devs against such a thing in the standard library ?
> How you guys are actually doing IO in racket ?
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Stephen Chang
A "read" variant that works with format strings would be a useful
addition I think.

Matthew, your solution is clever :) (but with symbols instead of strings).

Another alternative could be to use match:

#lang racket

(define (trim-brackets str)
  (string-trim str #rx"\\[|\\]|,"))

(define (pad n w)
  (~r n #:pad-string "0" #:min-width w))

(parameterize ([current-input-port (open-input-file "file.txt")])
  (for ([ln (in-lines)])
(match (string-split (trim-brackets ln) ", ")
  [(list (app string->number x)) (displayln x)]
  [(list (app string->number x) y (app string->number z))
   (printf "[~a, ~a, ~a]\n" (pad x 2) y (pad z 4))])))

or if you are willing to write a macro:

#lang racket

(define (trim-brackets str)
  (string-trim str #rx"\\[|\\]|,"))

(define (pad n w)
  (~r n #:pad-string "0" #:min-width w))

(define-match-expander numstr
  (syntax-rules () [(_ x) (app string->number x)]))

(parameterize ([current-input-port (open-input-file "file.txt")])
  (for ([ln (in-lines)])
(match (string-split (trim-brackets ln) ", ")
  [(list (numstr x)) (displayln x)]
  [(list (numstr x) y (numstr z))
   (printf "[~a, ~a, ~a]\n" (pad x 2) y (pad z 4))])))



(yes, I didnt close the port)

On Tue, Mar 22, 2016 at 6:34 PM, Matthew Butterick  wrote:
>> Then, for all rows, read and split the string. The best that i have found to 
>> do that is using regular expressions.
>>
>>   (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))
>>
>> Then you have to manually convert the substrings into values
>>
>>   (define a (string->number (second split-row)))
>>   (define b (third split-row))
>>   (define c (string->number (fourth split-row)))
>
> This kind of destructuring & conversion from strings to values can sometimes 
> be more conveniently handled by converting your source data into something 
> that looks like Racket S-expressions (in this case, by removing the commas) 
> and then calling `read` to do the rest, e.g.
>
> #lang racket
> (with-input-from-file "data.txt"
>   (λ _ (for/list ([ln (in-lines)])
>  (read (open-input-string (string-replace ln "," ""))
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] IO in racket is painful

2016-03-22 Thread Matthew Butterick
> Then, for all rows, read and split the string. The best that i have found to 
> do that is using regular expressions.
> 
>   (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))
> 
> Then you have to manually convert the substrings into values
> 
>   (define a (string->number (second split-row)))
>   (define b (third split-row))
>   (define c (string->number (fourth split-row)))

This kind of destructuring & conversion from strings to values can sometimes be 
more conveniently handled by converting your source data into something that 
looks like Racket S-expressions (in this case, by removing the commas) and then 
calling `read` to do the rest, e.g.

#lang racket
(with-input-from-file "data.txt"
  (λ _ (for/list ([ln (in-lines)])
 (read (open-input-string (string-replace ln "," ""))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] IO in racket is painful

2016-03-22 Thread rom cgb
Hi,

I recently started using Racket and i couldn't find a good alternative to C's 
scanf/printf in the racket standard library. When doing programming challenges, 
you often need to comply to a specific input/ouput thus having something like 
scanf for string to values and printf for values to string is comfy.

For example, let's say a challenge where you simply have to output the input 
but you need to translate the strings input into values and then those values 
back to strings.

The given input(and excepted ouput) is

  3
  [04, foo, 03.5]
  [05, bar, 04.6]
  [06, fun, 05.7]

In C, you would simply do

  #include 

  int main(void) 
  {
  int n;
  
  // Read number of rows
  scanf("%d\n", );
  
  // Output number of rows
  printf("%d\n", n);
  
  // Process rows
  for (unsigned int i; i < n; ++i)
  {
  int a;
  char b[20];
  float c;
  
  // Read row
  scanf("[%d, %[^,], %f]\n", , b, );
  
  // Output row
  printf("[%02d, %s, %04.1f]\n", a, b, c);
  }
  }

Now, for a solution in Racket, You first have to read the first line and 
convert it into a number.

  (define rows (string->number (read-line)))

Then, for all rows, read and split the string. The best that i have found to do 
that is using regular expressions.

  (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))

Then you have to manually convert the substrings into values

  (define a (string->number (second split-row)))
  (define b (third split-row))
  (define c (string->number (fourth split-row)))

Then you have to manually convert the values back into strings

  (printf "[~a, ~a, ~a]\n"
  (~a a #:width 2 #:align 'right #:pad-string "0")
  b
  (~r c #:min-width 4 #:precision 1 #:pad-string "0")))

This is way more tedious than with the classical input/output format, 
especially when you are doing coding challenges. 

Final Racket solution:

  #lang racket

  (define rows (string->number (read-line)))

  (for ([in-range rows])
(define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))
  
(define a (string->number (second split-row)))
(define b (third split-row))
(define c (string->number (fourth split-row)))

(printf "[~a, ~a, ~a]\n"
(~a a #:width 2 #:align 'right #:pad-string "0")
b
(~r c #:min-width 4 #:precision 1 #:pad-string "0")))


Having something like (not necessary the same specifiers as with printf)

  (string-scan "[%d, %s, %f]" "[45, foo, 10.9]") -> '(45 "foo" 10.9)

and a proper output formatter would be comfy. 

Are racket devs against such a thing in the standard library ?
How you guys are actually doing IO in racket ?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.