Ruby code improvements

Hello

I have made 2 scripts in ruby, first of all I explain what they do.
First program from list of people in text file creates rtf file with
cards it means file with colored table with persons. Second program do
the same but in html file. In first I can use gem library in seconde I’m
not allowed.

My teacher said that in both cases code could be two times shorter. He
also said that i’m not organising stuff in class and methods that could
be a proble if I start to write more advanced codes in future. I’m
asking where and how I could improve my code to be shorter and organised
in classed/method. I placed my notes in the comments.

require ‘rubygems’
require ‘rtf’
include RTF

def card(t, person, style1, style2, i)
style = CharacterStyle.new
x = i/2.0.floor
y = i % 2
if x % 2 == 0
style = style1
t[x][y].shading_colour = $olive
else
style = style2
t[x][y].shading_colour = $maroon
end
person = person.split(";")

I could bet that there’s some way to automatically apply line_break

command after all following lines.

t[x][y].apply(style) << "name: " + person[0]
t[x][y].line_break
t[x][y].apply(style) << "surname: " + person[1]
t[x][y].line_break
t[x][y].apply(style) << "date_of_birth: " + person[2]
t[x][y].line_break
t[x][y].apply(style) << "salary: " + person[3]
t[x][y].line_break
t[x][y].apply(style) << "phone: " + person[4]
t[x][y].line_break
t[x][y].apply(style) << "position: " + person[5]
t[x][y].line_break
t[x][y].apply(style) << "email: "+ person[6]
end

document = Document.new(Font.new(Font::ROMAN, ‘Times New Roman’), nil,
Document::CS_PC, Document::LC_POLISH)

I don’t like using a global variables there but applying them directly

in method card would slow down whole script.

$maroon = Colour.new(125, 0, 0)
$olive = Colour.new(125, 125, 0)
style1 = CharacterStyle.new
style1.font = Font.new(Font::MODERN, ‘Calibri’)
style1.foreground = $maroon
style1.underline = true
style2 = CharacterStyle.new
style2.font = Font.new(Font::ROMAN, ‘Times New Roman’)
style2.bold = true
style2.foreground = $olive
people = []
f = open(‘base.txt’, “r:UTF-8”) { |f| f.read }
f.each_line { |ln| people << ln }
array = document.table(people.length/2.0.ceil,2, 4000,4000,4000)

I don’t like using “i” variable as cell counter of table. I would like

to use some useful method instead of that.

i = 0
people.each {|person|
card(array, person, style1, style2, i)
i += 1
}
File.open(‘cards.rtf’, ‘w:UTF-8’) {|f| f.write(document.to_rtf)}


                        Second program

def b(text)
#{text}
end

def array(document, person, i)
person = person.split(’;’)

I don’t like the “i” variable. I think there is an other simple way

in ruby to do something diffrent in loop for every second element.

if i % 2 == 0
document << “


color1 = ‘maroon’
color2 = ‘olive’
else
color1 = ‘olive’
color2 = ‘maroon’
end

There would be great if i could organise array styles in methods.

document << “


document << b("name: ") + person[0] + “

document << b("surname: ") + person[1] + “

document << b("date_of_birth: ") + person[2] + “

document << b("salary: ") + person[3] + “

document << b("phone: ") + person[4] + “

document << b("position: ") + person[5] + “

document << b("email: ") + person[6] + “

document << “”
if i % 2 == 1
document << “”
end
end

people = []
f = open(‘base.txt’, “r:UTF-8”) { |f| f.read }
f.each_line { |ln| people << ln }
document = ‘’

I would like to create document as an object of some class.

document <<
"

"

i = 0
people.each { |person|
array(document, person, i)
i += 1
}

document <<
"

"

File.open(‘document.html’, ‘w:ISO-8859-2’) { |f| f.write document }

I’ve not took the time to read the entire script, but if your teacher
are telling you that about the code, meaby you should learn more about
OOP. And don’t be down, whit time you will be better organizing code.

Using OOP concepts you could divide your code into classes and objects,
like your teacher said, so you’d have a clean code.

For example a Person class that would be responsible to create a Person,
a Card class that would be responsible to read some data and interacte
with Persons, something like this.