Open ErezBinyamin opened 4 years ago
It seems to be a very interesting and useful adapter.
Please add your script with a pull-request, with a pull request as scripts/adapters/oeis.sh
,
and I will it bind it to the tree. We also should think about the output format to make it clearer
I am considering adding a feature to search for a code sample in a particular language (instead of just dumping all the code OEIS has) and potentially adding some syntax highlighting. Do you think this would be a worthwhile tool to add as an adapter? OEIS is a cheat sheet of sorts, especially considering the code samples it provides to replicate certain series.
I think it would be a very useful feature.
We could make it accessible two ways:
curl cheat.sh/oeis/A007318/python
curl cheat.sh/python/A007318
In both cases it would very helpful + the output could be automatically syntactically highlighted
Thank you for the pull-request; it was merged; now I have to bind the script to cheat.sh
pygmentize
from the script.OEIS Supported languages (I know of):
- MAPLE
- MATHEMATICA
- Axiom
- MAGMA
- PARI
- Python
- Sage
- Haskell
- Julia
- GAP
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, 1, 5, 10, 10, 5, 1 , 1, 6, 15, 20, 15, 6, 1, 1, 7, 21, 35, 35, 21, 7, 1, 1, 8, 28, 56, 70, 56, 28, 8, 1, 1, 9, 36, 84, 126, 126, 84, 36, 9, 1, 1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1, 1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1
"""
Pascal's triangle read by rows: C(n,k) = binomial(n,k) = n!/(k!*(n-k)!), 0 <= k <= n.
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, 1, 5, 10, 10, 5, 1 ...
"""
curl cheat.sh/python/A007318
"""
Pascal's triangle read by rows: C(n,k) = binomial(n,k) = n!/(k!*(n-k)!), 0 <= k <= n.
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, 1, 5, 10, 10, 5, 1 ...
a(n, k) = C(n,k) = binomial(n, k).
C(n, k) = C(n-1, k) + C(n-1, k-1).
The triangle is symmetric: C(n,k) = C(n,n-k).
a(n+1, m) = a(n, m) + a(n, m-1), a(n, -1) := 0, a(n, m) := 0, n<m; a(0, 0)=1.
C(n, k)=n!/(k!(n-k)!) if 0<=k<=n, otherwise 0.
G.f.: 1/(1-y-x*y) = Sum(C(n, k)*x^k*y^n, n, k>=0)
G.f.: 1/(1-x-y) = Sum(C(n+k, k)*x^k*y^n, n, k>=0).
G.f. for row n: (1+x)^n = Sum_{k=0..n} C(n, k)x^k.
G.f. for column n: x^n/(1-x)^n.
E.g.f.: A(x, y) = exp(x+x*y).
E.g.f. for column n: x^n*exp(x)/n!.
"""
# See Hobson link. Further programs:
def C(n, k):
if k < 0 or k > n:
return 0
res = 1
for i in range(k):
res *= (n - i) // (i + 1)
return res
# Robert FERREOL, Mar 31 2018
def C(n, k): from numpy import prod; return prod([(n-j)/(j+1) for j in range(k)])
def C(n, k): from functools import reduce; return reduce(lambda x, y: x*(n-y)//(1+y), range(k), 1) # Some characters longer, but using only integers.
# M. F. Hasler, Dec 13 2019
pygmentize
callsDo you think the FORMULA section is worthwhile as additional information?
We have special option, C
for the comments (to switch them on and off).
Compare:
$ curl cht.sh/python/remove+line?Q
f = open("yourfile.txt","r")
lines = f.readlines()
f.close()
f = open("yourfile.txt","w")
for line in lines:
if line!="nickname_to_delete"+"\n":
f.write(line)
f.close()
vs
$ curl cht.sh/python/remove+line
# Deleting a specific line in a file (python)
#
# Assuming your file is in the format of one nickname per line, use
# this.
#
# First, open the file:
f = open("yourfile.txt","r")
# Next, get all your lines from the file:
lines = f.readlines()
# Now you can close the file:
f.close()
# And reopen it in write mode:
f = open("yourfile.txt","w")
# Then, write your lines back, except the line you want to delete. You
# might want to change the "\n" to whatever line ending your file uses.
for line in lines:
if line!="nickname_to_delete"+"\n":
f.write(line)
# At the end, close the file again.
f.close()
# [houbysoft] [so/q/4710067] [cc by-sa 3.0]
Maybe we should use the same semantics here?
- Do you think the non-code-sample text should be printed in the form of a block comment?
Yes
Again, we have an option for that:
Compare
curl cht.sh/python/remove+line
vs
curl cht.sh/python/remove+line?C
- Do you think any other formatting changes would make the information more useful?
I think that it is enough, no additional formatting for this particular adapter is needed. Also see my comment at #193 (will add it now)
I am having a problem with cmd.py. Not all of the arguments are getting to the oeis.sh script or are not getting there properly.
Could you provide me with a conceptual data-flow that links events and files together? I am a bit lost.
Something like:
curl cht.sh/oeis/python+A2
-> cmd.py -> oeis.sh -> error_checker -> response_printer ->
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.
1, 2, 2, 1, 1, 2, 1, 2, 2, 1
(Python)
# For explanation see link.
def Kolakoski():
x = y = -1
while True:
yield [2, 1][x&1]
f = y &~ (y+1)
x ^= f
y = (y+1) | (f & (x>>1))
K = Kolakoski()
print([next(K) for _ in range(100)]) # David Eppstein, Oct 15 2016
I've tried to play with it a little bit, and see that some queries do not work:
Let us try from the beginning, and define the query format first.
What queries do we want to support:
oeis/1,2,3,4
oeis/A10
oeis/A10/python
oeis/1,2,3,4/python
Correct?
Currently none on them work. That is what I get:
$ curl cht.sh/oeis/1+2+3+4
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
$ curl cht.sh/oeis/A10
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
$ curl cht.sh/oeis/A10
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
$ curl cht.sh/oeis/A10/python
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
$ curl cht.sh/oeis/A10+python
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
$ curl cht.sh/oeis/python+A10
ID: A000010
Euler totient function phi(n): count numbers <= n and prime to n.
1, 1, 2, 2, 4, 2, 6, 4, 6, 4
I think that these problems are pretty trivial, and we will easily fix them, but let us define the query format first, just to know precisely what we are trying to achieve. Also, I will add a small todo section to the issue description. Please say, if I will forget any steps
Could you provide me with a conceptual data-flow that links events and files together? I am a bit lost. Something like: curl cht.sh/oeis/python+A2 -> cmd.py -> oeis.sh -> error_checker -> response_printer ->
Yes, it is correct. Some additional details:
If we specify markdown
as an output format
of the adapter, we can distinguish between code and text,
which will allow cheat.sh to format and highlight
the text according to its meaning (text or code)
@ErezBinyamin Thank you for the pull request (#209). It seems to work much better now, but several issues are still there (if you add #NUMBER to the commit message, it will be automatically mentioned in the issue, which is better for tracking; + it is better to split a PR into several PRs, if they do not directly relate to each other, to better isolate changes from each other, like in this case chmod and oeis changes).
I've played a little bit with it, and it seems to work pretty good. Several minor improvements:
would it be possible to get the list of available languages for some sequence? Something like:
curl cht.sh/oeis/A2/:list
Is it possible to specify that the resulting (output) sequence must start from the specified (input) and not merely contain it?
To activate automatic syntax highlighting/commenting, could you please modify the adapter in such way that the code in the answer is shifted with four spaces from the left? Like this:
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.
1, 2, 2, 1, 1, 2, 1, 2, 2, 1
(Python)
# For explanation see link.
def Kolakoski():
x = y = -1
while True:
yield [2, 1][x&1]
f = y &~ (y+1)
x ^= f
y = (y+1) | (f & (x>>1))
K = Kolakoski()
print([next(K) for _ in range(100)]) # David Eppstein, Oct 15 2016
Great feedback. I'm on it.
oeis/SEQ_ID/:list
I have not found a way to specify that a sequence must start with the numbers given (I could just implement that myself though). However, there are some interesting syntax tricks that we could implement like:
search sequence by author 2,3,6,16 author:Stanley
search sequence by phrase 2,3,6,16 "symmetric group"
and more:
id: ref: program:
seq: link: xref:
signed: formula: keyword:
name: example: author:
offset: maple: extension:
comment: mathematica:
These syntax tricks seem to directly correspond to the OEIS output section names. The way they work seems to be that the argument to trick program:Python
will result in OEIS only printing the sequences that have the string "Python" in their "program" section. Or more generically: For a given section and argument SECTION:ARGUMENT
OEIS will only print the sequences who's SECTION section contains the string ARGUMENT
How would you suggest these special search arguments be specified?
What should be the default behavior?
How many terms should be printed out for each sequence (currently 10) or how many digits/chars??
:list
implementationIn my open PR #210 :list
is implemented such that for a given sequence ID it prints a list of available languages for which there are available code snippets (Which you indicated was a desired feature earlier in the thread). What do you think about expanding :list
to not only generate a list of languages, but rather to generate a list of sections that could be printed. For example:
curl cheat.sh/oeis/A2/:list
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.1, 2, 2, 1, 1, 2, 1, 2, 2, 1
offset
comments
references
links
formula
example
maple
mathematica
pari
haskell
python
crossrefs
keyword
author
extension
status
Then a user could pick the section they wanted:
curl cheat.sh/oeis/A2/example
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.1, 2, 2, 1, 1, 2, 1, 2, 2, 1
Start with a(1) = 1. By definition of the sequence, this says that the first run has length 1, so it must be a single 1, and a(2) = 2. Thus, the second run (which starts with this 2) must have length 2, so the third term must be also be a(3) = 2, and the fourth term can't be a 2, so must be a(4) = 1. Since a(3) = 2, the third run must have length 2, so we deduce a(5) = 1, a(6) = 2, and so on. The correction I made was to change a(4) to a(5) and a(5) to a(6).
Making the oeis adapters usage taking two forms:
# Search sequences by pattern
curl cheat.sh/oeis/1, 2, 2, 1, 1, 2, 1, 2, 2, 1
# Search sequence section by sequence ID
curl cheat.sh/oeis/A2/python
curl cheat.sh/oeis/A2+maple
curl cheat.sh/oeis/A2/example
curl cheat.sh/oeis/A2+formula
I am experimenting with it;
some queries seem to fail:
$ curl cht.sh/oeis/A2/:list
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.
1, 2, 2, 1, 1, 2, 1, 2, 2, 1
LIST unavailable. Use :list to view available languages.
Link to source: https://oeis.org/A000002
It is better now:
$ curl cht.sh/oeis/A2/:list
ID: A000002
Kolakoski sequence: a(n) is length of n-th run; a(1) = 1; sequence consists just of 1's and 2's.
1, 2, 2, 1, 1, 2, 1, 2, 2, 1
maple
mathematica
Haskell
PARI
Python
Link to source: https://oeis.org/A000002
but it must be:
$ curl cht.sh/oeis/A2/:list
maple
mathematica
Haskell
PARI
Python
I've activated comments and syntax highlighting (see the commit above), it looks pretty good, but it does not recognize yet the programming language (based on _info.yaml from cheat.sheets; I will activate it now too)
Commenting and syntax highlighting works:
$ curl cht.sh/oeis/A10/python
# ID: A000010
# Euler totient function phi(n): count numbers <= n and prime to n.
#
# 1, 1, 2, 2, 4, 2, 6, 4, 6, 4
#
# Python
from sympy.ntheory import totient
print([totient(i) for i in range(1, 70)]) # Indranil Ghosh, Mar 17 2017
# Link to source: https://oeis.org/A000010
Please test.
Could you please fix a couple of minor things:
Link to source: https://oeis.org/A000010
into [https://oeis.org/A000010]
In #213
:list
output is now only the list of languages (no additional sequence info) I have just made a realization and will be doing a full re-write of oeis.sh
. I will make a new PR for it.
This is the realization: https://oeis.org/search?q=id:A000002&fmt=text And also: https://oeis.org/search?q=signed:1,2,3,4&fmt=short
I have been parsing HTML instead of simply reading text.
No functional changes will be made, but I am sure this will speed up search times.
I've merged and deployed it, please test
(regarding html/txt: I think it will not speed up parsing much, but it does not matter; text is of course better to use because this solution will be guaranteed more robust)
It is much better now. I am not a fan of the C-style block comment though, it seems a bit messy. The asterisks going down the page distract from the content a bit. I am not sure where that is implemented, but perhaps a single /*
and closing */
would be sufficient.
Why have you mentioned C-style? Do we have also C programs?
I think that we need support for several new programming languages (comments + syntax):
maple
mathematica
Axiom
Haskell
MAGMA
Maxima
PARI
Python
Sage
For example, from these languages only mathematica, python and haskell are supported. Do you have a full list of all languages that must be supported?
Another problem:
Some code is not correctly extracted by the script:
{-
- ID: A000010
- Euler totient function phi(n): count numbers <= n and prime to n.
-
- 1, 1, 2, 2, 4, 2, 6, 4, 6, 4
-
- haskell (Haskell) a n = length (filter (==1) (map (gcd n) [1..n]))
- Allan C. Wechsler, Dec 29 2014
-
- [https://oeis.org/A000010]
-}
And it must be:
{-
- ID: A000010
- Euler totient function phi(n): count numbers <= n and prime to n.
-
- 1, 1, 2, 2, 4, 2, 6, 4, 6, 4
-
-}
a n = length (filter (==1) (map (gcd n) [1..n]))
{-
- Allan C. Wechsler, Dec 29 2014
-
- [https://oeis.org/A000010]
-}
I don't know if you are aware of this feature,
if you want to see code only without comments, you can add ?Q
:
$ curl cht.sh/oeis/A10/python?Q
from sympy.ntheory import totient
print([totient(i) for i in range(1, 70)]) # Indranil Ghosh, Mar 17 2017
By the way, is it possible to cut automatically the contributor name, and print it at the same line where the external link is printed:
{- [https://oeis.org/A000010] [Allan C. Wechsler, Dec 29 2014] -}
I added oeis
cheat sheet with some syntax description:
$ curl cheat.sh/oeis
# oeis
#
# The On-Line Encyclopedia of Integer Sequences (OEIS),
# also cited simply as Sloane's, is an online database of integer sequences.
# Find all possible OEIS sequences for some sequence (1,1,1,1...)
curl cheat.sh/oeis/1+1+1+1
# Describe an OEIS sequence (A2)
curl cheat.sh/oeis/A2
# Implementation of the A2 OEIS sequence in Python
curl cheat.sh/oeis/A2/python
# List all available implementations of the A2 OEIS sequence
curl cheat.sh/oeis/A2/:list
I understand why you asked about C formatting, it is used for formatting currently, but we can change it into shell formatting or whatever
ID: A000009
Expansion of Product_{m >= 1} (1 + x^m); number of partitions of n into distinct parts; number of partitions of n into odd parts.
1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 22, 27, 32, 38, 46, 54, 64, 76, 89, 104, 122, 142, 165, 192, 222, 256 ...
PartitionsQ[Range[0, 60]] (* [1] *)
a[ n_] := SeriesCoefficient[ Product[ 1 + x^k, {k, n}], {x, 0, n}]; (* [2] *)
a[ n_] := SeriesCoefficient[ 1 / Product[ 1 - x^k, {k, 1, n, 2}], {x, 0, n}]; (* [2] *)
a[ n_] := With[ {t = Log[q] / (2 Pi I)}, SeriesCoefficient[ q^(-1/24) DedekindEta[2 t] / DedekindEta[ t], {q, 0, n}]]; (* [2] *)
a[ n_] := SeriesCoefficient[ 1 / QPochhammer[ x, x^2], {x, 0, n}]; (* [2] *)
a[ n_] := SeriesCoefficient[ Series[ QHypergeometricPFQ[ {q}, {q x}, q, - q x], {q, 0, n}] /. x -> 1, {q, 0, n}]; (* [2] *)
a[ n_] := SeriesCoefficient[ QHypergeometricPFQ[{}, {}, q, -1] / 2, {q, 0, n}]; (* [2] *)
nmax = 60; CoefficientList[Series[Exp[Sum[(-1)^(k+1)/k*x^k/(1-x^k), {k, 1, nmax}]], {x, 0, nmax}], x] (* [3] *)
nmax = 100; poly = ConstantArray[0, nmax + 1]; poly[[1]] = 1; poly[[2]] = 1; Do[Do[poly[[j + 1]] += poly[[j - k + 1]], {j, nmax, k, -1}];, {k, 2, nmax}]; poly (* [3] *)
[1] [Harvey Dale]
[2] [Michael Somos]
[3] [Vaclav Kotesovec]
[https://oeis.org/search?q=id:A000009]
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
ARIBAS | DERIVE | Java | mathematica | PAARI | Python3 | sh |
Axiom | End | JavaScript | MATLAB | Pari | R | Smalltalk |
AXIOM | Excel | Julia | Maxima | PARI | Racket | S/R |
bash/plantri | FORTRAN | LiE | MuPAD | Pascal | Ruby | TI-BASIC |
bc | GAP | Macsyma | n | Perl | Sage | t(n |
C | Haskel | Magma | nauty/bash | Prime95 | SageMath | TOPCOM |
C# | Haskell | MAGMA | python | Scala |
curl cheat.sh/oeis/$RANDOM/mathematica
continually ended up with misplaced error messages (seemingly from grep
)
(*
* ID: A022428
* Binary file /tmp/oeis/doc.html matches
*
* Binary file /tmp/oeis/doc.html matchesBinary file /tmp/oeis/doc.html
* matchesBinary file /tmp/oeis/doc.html matches ...
*)
Binary file /tmp/oeis/doc.html matches
( [https://oeis.org/search?q=id:A022428] )
I've merged and deployed it; it looks much better now:
$ curl cht.sh/oeis/29069/mathematica
(*
* ID: A029069
* Expansion of 1/((1-x)*(1-x^4)*(1-x^5)*(1-x^12)).
*
* 1, 1, 1, 1, 2, 3, 3, 3, 4, 5, 6, 6, 8, 9, 10, 11, 13, 15, 16, 17, 20,
* 22, 24, 25, 29, 32, 34, 36, 40, 44 ...
*)
CoefficientList[Series[1/((1-x)(1-x^4)(1-x^5)(1-x^12)),{x,0,60}],x] (* [1] *)
(*
* [1] [Harvey P\. Dale, Aug 11 2011]
* [https://oeis.org/search?q=id:A029069]
*)
Just a minor thing to be fixed:
Sequence search ls commented like C, and highlighted like shell. The question is how we should comment it? Like shell? I understand that we can just leave it as text, without commenting it out, but actually we on cheat.sh have such a rule that text must be displayed as comments, and code as code.
We could make an exception for OEIS though, because this rule does not seem to make sense for it.
How would you suggest these special search arguments be specified?
We can specify arguments either inline 1+2+3+author:Stanley
or as URL arguments:
1+2+3?author=Stanley
I tend to the first option.
What should be the default behavior? Should we only print sequences that start with the numbers given? Should we print sequences that contain a sub-sequence of the numbers given?
If we simulate grep semantics, it should be "contain" instead of start,
and to force the "start" search, the sequence must be prepended with ^
How many terms should be printed out for each sequence (currently 10) or how many digits/chars??
I think 10 is ok, but we need to support an additional parameter for longer output (?n=20
) and maybe for ranges
I did some experiments. The current functionality is like grep in the sequence results simply "contain" the sequence provided. Example1 Example2 Example3
Some of those examples the sub-sequence numbers do not even appear in the result, which gives rise to a new question:
1+2+3+<argument>:<value>
^
?n=<len>
Erez hi! I am back to my opensource projects; sorry for the long disappearance. Let us finalize this issue, if you are available? I think it is almost done already; we should make the last missing things and publish it
I'm also a bit tied up atm. Will definitely try to finish up those last improvements. The OEIS adapter is certainly almost there. I'm working out how to implement the same search UI on the OEIS website
I'm working out how to implement the same search UI on the OEIS website
What do you mean? What search UI do you mean?
I mean giving cheat.sh users access to the same search parameters supported by OEIS.
Need to finish python port #376 I expect a prototype by the end of this week
Todo
curl cheat.sh/oeis/$RANDOM/mathematica
continually ended up with misplaced error messages (seemingly fromgrep
)Adapter:
cheat.sheets:
Details
The On-Line Encyclopedia of Integer Sequences is a great resource for programmers. It'd be cool to browse sequences from the command line and potentially get code samples to copy and paste. I have a working prototype of the script here. Currently it can either take one argument or many. If many are supplied, a list of potential sequence matches is returned, of one argument is supplied, then the sequence with that ID and a colorized code segment are returned.
Example usage finding a sequence by pattern
Example usage looking up a particular sequence by ID