I am trying to calculate pi and put it into a picture in ruby.
It works up until lines 36 (where it doesn't write pi [without a decimal place] to file) and 63 (where it only writes the off white color to pi.png). As a side note, the program doesn't seem to be making the right number of digits of pi ($looptimes
)
Here is my ruby file:
pi.rb
#get width and height of picture
p 'width of pi'
$w = gets.chomp.to_i
p 'height of pi'
$h = gets.chomp.to_i
$looptimes = $w*$h
#calculate pi
def pi
q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
dot = nil
$looptimes.times do
if 4*q+r-t < n*t
yield n
nr = 10*(r-n*t)
n = ((10*(3*q+r)) / t) - 10*n
q *= 10
r = nr
else
nr = (2*q+r) * l
nn = (q*(7*k+2)+r*l) / (t*l)
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr
end
end
end
#create and write to file
File.new("pi.txt", 'w')
File.open("pi.txt", 'w') { |pitxt|
pitxt.write(pi {|digit| print digit; $stdout.flush})}
def read_file(file_name)
file = File.open(file_name, "r")
data = file.read
file.close
return data
end
pinumber = read_file("./pi.txt")
pinumber.to_s
require 'chunky_png'
#make picture
image = ChunkyPNG::Image.new($w,$h)
image.save('pi.png')
image = ChunkyPNG::Image.from_file('pi.png')
#draw pixels
for $pointw in 0...$w do
for $pointh in 0...$h do
for j in 0...$looptimes do
if pinumber[j] = '0'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(244,244,244)
image.save('pi.png')
elsif pinumber[j] = '1'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(231,47,39)
image.save('pi.png')
elsif pinumber[j] = '2'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(241,176,102)
image.save('pi.png')
elsif pinumber[j] = '3'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(255,228,15)
image.save('pi.png')
elsif pinumber[j] = '4'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(18,154,47)
image.save('pi.png')
elsif pinumber[j] = '5'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(126,188,209)
image.save('pi.png')
elsif pinumber[j] = '6'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(3,86,155)
image.save('pi.png')
elsif pinumber[j] = '7'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(46,20,141)
image.save('pi.png')
elsif pinumber[j] = '8'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(152,152,152)
image.save('pi.png')
elsif pinumber[j] = '9'
image[$pointw,$pointh] = ChunkyPNG::Color.rgb(10,10,10)
image.save('pi.png')
end
end
end
end
Please let me know if you have any ideas.
Also, are there any more efficient ways to do this? Thank you all for your help!
The
write
command, as you used it, would write the return value ofpi
to the file. The returned value frompi
is not a string of digits, but the last value calculated inside the routine (which happens to always be the last assignment tor
)The closest fix (i.e. the least amount you need to change to get it to work) is to output the yielded digits to the file, which you are already doing with printing to stdout:
This should at least get you the digits you need into the text file.
You have several more mistakes in your script. I suggest you take things more slowly (in fact I recommend you remove the image-writing code as it is, and have another go!) Feel free to ask more questions on SO as you progress. For your next question, instead of presenting the entire script and asking "what's wrong with this", try to write a simple isolated example that demonstrates what you are trying to do, and has a single thing that you cannot get to work. For example, now you already have the digits of pi correct, there is no need to ask about that code - the image-writing part should be able to cope with any string of digits. You may even find that putting examples together allows you to answer your own question.