how to print HyExpression in python? - hy

how to print a object HyExpression as
HyExpression([
HyExpression([
HySymbol('/'),
HyInteger(2)]),
HyExpression([
HyString('ceil')])])
as
'((/ 2) ("ceil"))'
in console ?

ah! I have found the answer and its as follows hy_repr!
just use in .py
from hy.contrib.hy_repr import hy_repr
input_rule_list = '["đźš±?" ((/ 2) ("ceil"))]'
expr_input_list = hy.read_str(input_rule_list) #HyExpression
#do something with this expr
print(hy_repr(expr_rule_parsed))
(cond [((get predicators "🚱?") 🏷) [((/ 2)) (("ceil"))]])
Cool!

Related

Get related articles based on tags in Ruby

I’m trying to display a related section based on the article’s tags. Any articles that have similar tags should be displayed.
The idea is to iterate the article’s tags and see if any other articles have those tags.
If yes, then add that article to a related = [] array of articles I can retrieve later.
Article A: tags: [chris, mark, scott]
Article B: tags: [mark, scott]
Article C: tags: [alex, mike, john]
Article A has as related the Article B and vice-versa.
Here’s the code:
files = Dir[ROOT + 'articles/*']
# parse file
def parse(fn)
res = meta(fn)
res[:body] = PandocRuby.new(body(fn), from: 'markdown').to_html
res[:pagedescription] = res[:description]
res[:taglist] = []
if res[:tags]
res[:tags] = res[:tags].map do |x|
res[:taglist] << '%s' % [x, x]
'%s' % [x, x]
end.join(', ')
end
res
end
# get related articles
def related_articles(articles)
related = []
articles[:tags].each do |tag|
articles.each do |item|
if item[:tags] != nil && item[:tags].include?(tag)
related << item unless articles.include?(item)
end
end
end
related
end
articles = files.map {|fn| parse(fn)}.sort_by {|x| x[:date]}
articles = related_articles(articles)
Throws this error:
no implicit conversion of Symbol into Integer (TypeError)
Another thing I tried was this:
# To generate related articles
def related_articles(articles)
related = []
articles.each do |article|
article[:tags].each do |tag|
articles.each do |item|
if item[:tags] != nil && item[:tags].include?(tag)
related << item unless articles.include?(item)
end
end
end
end
related
end
But now the error says:
undefined method `each' for "tagname":String (NoMethodError)
Help a Ruby noob? What am I doing wrong? Thanks!
As an aside to the main question, I tried rewriting the tag section of the code, but still no luck:
res[:taglist] = []
if res[:tags]
res[:tags] = res[:tags].map do |x|
res[:taglist] << '' + x + ''
'' + x + ''
end.join(', ')
end
In your first attempt, the problem is in articles[:tags]. articles is an array, so you cannot access it using a symbol key.
The second attempt fails because article[:tags] is a string (from the parse function, you get the original tags, transform to HTML and then join). The :taglist key instead contains an array, you could use it.
Finally, the "related" array should be per-article so neither implementation could possibly solve your issue, as both return a single array for all your set of articles.
You probably need a two pass:
def parse(fn)
res = meta(fn)
res[:body] = PandocRuby.new(body(fn), from: 'markdown').to_html
res[:pagedescription] = res[:description]
res[:tags] ||= [] # and don't touch it
res[:tags_as_links] = res[:tags].map { |x| "#{x}" }
res[:tags_as_string] = res[:tags_as_links].join(', ')
res
end
articles = files.map { |fn| parse(fn) }
# convert each article into a hash like
# {tag1 => [self], tag2 => [self]}
# and then reduce by merge
taggings = articles
.map { |a| a[:tags].product([[a]]).to_h }
.reduce { |a, b| a.merge(b) { |_, v1, v2| v1 | v2 } }
# now read them back into the articles
articles.each do |article|
article[:related] = article[:tags]
.flat_map { |tag| taggings[tag] }
.uniq
# remove the article itself
article[:related] -= [article]
end

Class-Array Interaction Ruby

I'm trying to set up a program to help me take care of grading for students in a class. I've set it up to make a class of student then to read in from the file (something I'm not very familiar with in Ruby) via an array. My programming experience is in java so if there are errors that can be explained by that I apologize. Thank you in advance for your help.
class Student
def initialize(str_LastName, str_FirstName, arr_Score)
#str_LastName = str_LastName
#str_FirstName = str_FirstName
#arr_Score = arr_Score
str_Grade = ""
int_OutOf = 415
end
def get_LastName
str_LastName
end
def get_FirstName
str_FirstName
end
def get_Grade
str_Grade
end
def set_TotalScore()
sum = 0
arr_Score.each do |item|
sum += item
end
arr_Score[12] = sum
end
def set_Grade
if arr_Score[12]/int_OutOf >= 0.9
str_Grade = "A"
elsif arr_Score[12]/int_OutOf >= 0.8
str_Grade = "B"
elsif arr_Score[12]/int_OutOf >= 0.7
str_Grade = "C"
elsif arr_Score[12]/int_OutOf >= 0.6
str_Grade = "D"
else
str_Grade = "F"
end
end
end
def main
file_name = "Grades"
arr_students = Array.new(31)
arr_scores = Array.new(12)
int_i = 0
file_io = open(file_name).readlines.each do |line|
array = line.split(",").map(&:strip)
student = Student.new(array[0],array[1],array[2..-2]) #the final element in the array is for the final score
arr_students[int_i] = student
puts "read #{arr_students[int_i]}"
end
file_name = "Graded"
file_io = open(file_name,"a+")
arr_students.each do |student|
set_TotalScore
set_Grade
file.io_write(student)
puts "write #{student}"
end
end
main if __FILE__==$0
Here is my run at it. I tried to stay true in general to the original intent of your code while introducing more Rubyish ways of doing things.
class Student
def initialize(firstname, lastname, *scores)
#firstname, #lastname, #scores = firstname, lastname, scores
end
def total_score
#scores.map(&:to_i).inject(:+)
end
def grade
raise "TOO HIGH!" if total_score > MAX_SCORE
case total_score / MAX_SCORE
when 0.9..1.0; "A"
when 0.8...0.9; "B"
when 0.7...0.8; "C"
when 0.6...0.7; "D"
else "F"
end
end
def to_s
"#{#lastname}, #{#firstname}: #{total_score}, #{grade}"
end
end
MAX_SCORE = 415.0
DATA.each_line do |line|
arr = line.split(",").map(&:strip)
student = Student.new *arr
puts student
end
__END__
Herb,Goldberg,22,99,44,22,88,88
Mark,Sullivan,77,88,88,44,33
You can read and write to files like this(not tested):
outfile = File.open("Graded", "a+")
File.open("Grades").each_line do |line|
...
outfile.puts student
end
outfile.close
We can not easily reproduce your code because you open a file called "Grades" and we do not have or know of its content.
You should also add some code to first check whether your file exists, before continuing - right now your script exits with a Errno::ENOENT.
I would also suggest putting the logic in main into your class instead - let your class handle everything.
In the part:
if __FILE__ == $PROGRAM_NAME
end
You can then simply initialize your class with a simple call such as:
Foobar.new(ARGV)
You described the "Grades" file but I did not understand what you wrote - it would be easier if you could link in to a sample, like via a pastie or gist, then link it in; and to also say what the part is that is not working, which is also unclear.
The style issues are secondary, I consider your code ok - the other poster here does not.
You should go through codecademy to get your ruby syntax down.
To access your initialized instance variables (#str_LastName (which should be #last_name), etc) you need to use "attr_reader :str_LastName", preferably at the top of the class. That'll definite you getter (setter is attr_writer, both is attr_accessor).
You can also do a sum on an array like this: [1,4,6,7].inject(:+).
Does Java not allow case statements? You should use that in set_grade. You also don't need to initialize str_Grade. In set grade, you could do #grade_letter ||= "A", and then calling set_grade will return that value on each call.
I didn't look through your main method. It's ugly though. Ruby methods probably shouldn't be more than 5 lines long.

Test page for mod_wsgi

mod_python has a test page script which emits information about the server configuration. You can put
SetHandler mod_python
PythonHandler mod_python.testhandler
into your .htaccess and it displays the page.
Now my question: Does something similiar exist for mod_wsgi as well?
No. You can create something kind of helpful by iterating over the keys of environ, though:
def application(env, respond):
respond('200 OK', [('Content-Type', 'text/plain')])
return ['\n'.join('%s: %s' % (k, v) for (k, v) in env.iteritems())]
I have now put together something like a test page here. For your convenience, I'll share it with you here:
def tag(t, **k):
kk = ''.join(' %s=%r' % kv for kv in k.items())
format = '<%s%s>%%s</%s>' % (t, kk, t)
return lambda content: format % content
def table(d):
from cgi import escape
escq = lambda s: escape(s, quote=True)
tr = tag('tr')
th = tag('th')
td_code = lambda content: tag('td')(tag('code')(content))
return tag('table', border='1')(''.join((
'\n\t' + tr(th('Key') + th('Value') + th('Repr')) + '\n',
''.join(('\t' + tr(td_code('%s') + td_code('%s') + td_code('%s')) + '\n') % (k, escq(str(v)), escq(repr(v))) for k, v in sorted(d.items())),
))) + '\n'
def application(environ, start_response):
import os
l = []
from wsgiref.headers import Headers
h = Headers(l)
h.add_header('Content-Type', 'text/html')
start_response('200 OK', l)
yield '<html><head><title>my mod_wsgi test page</title></head><body>\n'
# yield '<h3>General information</h3>\n'
# yield table({})
yield '<h3>Process info</h3>\n'
yield table(dict(
wd=os.getcwd(),
pid=os.getpid(),
ppid=os.getppid(),
uid=os.getuid(),
gid=os.getgid(),
))
yield '<h3>Environment</h3>\n'
yield table(environ)

How do I check for pangrams in a line in ruby?

Some of you may notice I'm already back with the same painful code already. I'm not sure if the other question is still open or not once I accept an answer.
Now the problem is a little simpler. I found some code that checked for pangrams. It use to be def pangram?('sentence') but I needed line to go in there so I tried changing it to def pangram?(line). It doesn't seem to mesh well with my coding style and doesn't work. I tried to use .contain('a' . . 'z') to check for a pangram but someone I know tried that and it didn't work. Also google isn't much help either.
Any ideas for how I could check for pangrams in an if stmt?
# To change this template, choose Tools | Templates
# and open the template in the editor
# This program reads a file line by line,
#separating lines by writing into certain text files.
#PPQ - Pangrams, Palindromes, and Quotes
class PPQ
def pangram?(line)
unused_letters = ('a'..'z').to_a - line.downcase.chars.to_a
unused_letters.empty?
end
def categorize
file_pangram = File.new('pangram.txt', 'w')
file_palindrome = File.new('palindrome.txt', 'w')
file_quotes = File.new('quotes.txt','w')
File.open('ruby1.txt','r') do |file|
while line = file.gets
if(line.reverse == line)
file_palindrome.write line
elsif(pangram?(line)== true)
file_pangram.write line
else
file_quotes.write line
end
end
end
file.close
file_pangram.close
file_palindrome.close
file_quotes.close
end
end
my_ruby_assignment = PPQ.new
my_ruby_assignment.categorize
I'm partial to simpler syntax, something like
def pangram?(line)
('a'..'z').all? { |word| line.downcase.include? (word) }
end
if pangram?(line) then file_pangram.write line end
def pangram?(string)
str = string.chars.map(&:downcase)
letters =('a'..'z').to_a
result = true
letters.each do |l|
if !(str.include? l.downcase)
result = false
break
end
end
result
end

TypeError: invalid file: When trying to make a file name a variable

Hi I am trying to represent a file location as a variable because the finial script will be run on another machine. This is the code I have tried followed by the error I get. It seems to me that some how python is adding "\" and that is causing the problem. If that is the case how do I get it not to insert the "\"? Thank you
F = 'C:\Documents and Settings\myfile.txt','r'
f = open(F)
and the error
TypeError: invalid file: ('C:\\Documents and Settings\\myfile.txt', 'r')
From the docs:
http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files
Try this:
F = r'C:\Documents and Settings\myfile.txt'
f = open(F, 'r')
About the "double backslashes" - you need to escape backslashes in your strings or use r'string', see this:
http://docs.python.org/release/2.5.2/ref/strings.html
E.g. try this:
>>> a = 'a\nb'
>>> print a
a
b
To get what you expect, you need this:
>>> a = r'a\nb'
>>> print a
a\nb
or this:
>>> a = 'a\\nb'
>>> print a
a\nb
Try
f=open('C:\Documents and Settings\myfile.txt','r')
Instead of using the variable F. the way you have it 'r' is part of the file name, which it is not.
Instead of writing / or \, you should do this:
import os
F = os.path.join(
"C:",
os.path.join(
"Documents and Settings", "myfile.txt"
)
)
f = open(F, 'r')`
so that it uses / or \ according to your os.
(Although if you write C:/ it must mean you want to run your code on Windows... Hum...)

Resources