Get string class method called on - Ruby/Crystal - crystal-lang

I've been extending the string class in Crystal to support a "center" method. I have made the ability to get width and height, and I have most of the other parts. I just want this:
class String
def center
(I::Terminal.get_size.col / 2).times do #Half of screen width
print " "
end
#puts text that method was called on
end
end
puts "text".center #I want to puts "text" after my spacing

You don't need the times block. You can use String#rjust instead.
This code works in both Ruby and Crystal
(assuming you have the terminal width sorted out through I::Terminal.get_size.col)
class String
def center(width = nil)
width ||= I::Terminal.get_size.col
half_width = (width / 2).to_i
half_size = (self.size / 2).to_i
self.rjust(half_width + half_size)
end
end
puts "this is a nice text".center 80
I noticed you tagged this question as Crystal, but you ask about Ruby/Crystal - just in case you are using Ruby, know that you don't need it, since it is already implemented.

Related

This cell duplicates image in that cell in spreadsheet?

Very simple. Cell A1 has an image in it, which I supply through Insert:Picture:From File...
Now I want Cell A3 to automatically show the same picture. I simply can't find a way-- certainly the "=" doesn't work. At this point, I don't care if the images are "links" or embedded, I just want it to work. Can it? Thx.
Edit, 09-01-17, based on Jim K's idea, here's macro code I have installed:
REM ***** BASIC *****
Private oListener as Object
Private cellA1 as Object
Sub AddListener
Dim Doc, Sheet, Cell as Object
Doc = ThisComponent
Sheet = Doc.Sheets.getByName("Sheet1")
cellA1 = Sheet.getCellrangeByName("A1")
'create a listener
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener")
'register the listener
cellA1.addModifyListener(oListener)
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellA1.removeModifyListener(oListener)
End Sub
' macro jumps here when oListener detects modification of Sheet
Sub Modify_modified(oEv)
Doc = ThisComponent
Sheet = Doc.Sheets.getByIndex(0)
originCell = Sheet.getCellByPosition(0,0)
originValue = originCell.Value
if originValue then
print "originValue is " & originValue
else
print "originValue zero"
end if
End Sub
The problem, ironically, is that it works. It works for integers and {non-value}, I mean an empty cell.
So any integer not zero prints TRUE, zero prints FALSE, and empty cell prints FALSE.
But that's where it quits working-- any kind of string "asdf" also returns FALSE.
Maybe that could be fixed, but there's something a lot worse: When I paste an image in the cell, or use the Insert/Image/From File... menu, or Cut an existing image... Nothing happens! The Sheet Modified business does not trigger the expected routine.
Any hope? Thx.
As you discovered, the solution in my comment does not work, because the Content changed event will not trigger when images are added. I looked into other events as well, but they did not work either.
So instead, we can set up a function that runs periodically. Each time it runs, it checks the count of images, and if any have been added or removed, it calls update_copied_images() below, which currently simply reports the value of cell A1, as in your code.
As explained here, I have not gotten a timer loop to work in Basic without crashing, so we can use Python instead (a better language, so this is not a drawback in my opinion).
import time
from threading import Thread
import uno
COLUMN_A, COLUMN_B, COLUMN_C = 0, 1, 2
FIRST_ROW = 0
def start_counting_images(action_event=None):
t = Thread(target = keep_counting_images)
t.start()
def keep_counting_images():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.getSheets().getByIndex(0)
oDrawPage = oSheet.getDrawPage()
messageCell = oSheet.getCellByPosition(COLUMN_C, FIRST_ROW)
messageCell.setString("Starting...")
prevCount = -1
while hasattr(oDoc, 'calculateAll'): # keep going until document is closed
count = oDrawPage.Count
if prevCount == -1 or prevCount != count:
prevCount = count
messageCell.setString("Number of Images: " + str(prevCount))
update_copied_images(oSheet)
time.sleep(1)
def update_copied_images(oSheet):
originCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
originString = originCell.getString()
messageCell = oSheet.getCellByPosition(COLUMN_B, FIRST_ROW)
if len(originString):
messageCell.setString("originString '" + originString + "'")
else:
messageCell.setString("originString length is zero")
g_exportedScripts = start_counting_images,
To run, go to Tools -> Macros -> Run Macro, find the .py file under My Macros where you put this code, and run start_counting_images.

Create instance of class from list (Python 2.7)

I'm trying to make a simple RPG game. I have a list of people that will be in the game, and want to create a character for each of them.
people = ['Mike','Tom']
class Character(object):
def __init__(self,name):
self.name = name
self.health = '100'
for x in people:
[x] = Character(x) # This is where I don't know what to do / if it's possible
That way I can call a character easily like
for x in people:
print ("%s: %s health" % (people[x].name, people[x].health))
Is such a thing possible, or am I going about this wrong? I read over How do I create a variable number of variables? but it seemed like dictionaries were the ultimate fix for their problem, and I have no idea how that would work in this situation.
It looks like you're just wanting to keep a list of Character objects. You don't need to reference people once you have that.
characters = [Character(person) for person in people]
Then, to print the character stats:
for c in characters:
print ("%s: %s health" % (c.name, c.health))

Move to the middle of a block code

Using Vim I'm trying to move the cursor in the middle of a code block, but I can't figure out how to do this :
//cursor is for instance here.
{
//or here
//some code
// .... **** move cursor here ****
//some more code
}
The final idea is to have a shortcut that saves the current position, moves the cursor in the middle of the code block, sets the current line to the middle of the screen (with the shortcut "zz"), and then moves back to the saved position.
I'd prefer a built-in vim function, but a plugin works too.
EDIT: This is for c++ and so I want it for brackets {}.
I gave it a (quick and dirty) go:
function! Middleize()
" use ]M to jump to either the end of the current method if we are in it
" or the start of the next method if we are above the method
normal! ]M
" we record the current line number
let first_line = line('.')
" we go to the other end of the method
normal! %
" we record the current line number
let second_line = line('.')
" we started either from the top or from the bottom of the method
" so we have to take that into account when calculating the number
" of the line we want to jump to
if first_line < second_line
let middle_line = first_line + ((second_line - first_line) / 2)
else
let middle_line = ((first_line - second_line) / 2) + second_line
endif
" let's go!
execute "normal! " . middle_line . "Gzz"
endfunction
nnoremap <F5> :call Middleize()<CR>
More of a general solution but might be useful - the easy-motion plugin allows you to jump all over the place with great precision.
For example:
<Leader><Leader>w (default) - 'word motion'
g
Then to jump back, you'd just do the same thing backwards (in this case, <Leader><Leader>b g.
This doesn't set the current line to the middle of the screen, although you can :set scrolloff=9999 to have the middle of the screen follow your cursor around.
This won't give you exactly what you want, but it'll get text of the function on the screen (assuming it's not too long).
ma - set a mark at the current cursor position.
Repeatedly press } (jump ahead by a paragraph) until you can see the code you want.
`a - return to the mark you set.
A "paragraph" in vim terms is a group of consecutive non-blank lines. It's a nice approximation for a block of code. Also note that you can use any letter for the mark command, so there can be up to 52 of them active at once.

How to insert spaces to option text (select)?

I have form:
class Form(forms.ModelForm):
id = forms.ModelChoiceField(queryset=Category.objects.all(), widget=forms.HiddenInput())
def choices(self):
items = ...query for items...
for il in items:
prefix = ''
choices = []
for i in range(0,il.depth):
prefix = prefix + " "
il.name = prefix + il.name
choices.append((il.id,il.language))
self.fields['parent'].choices = choices
but this show:
category name
in option. How to do it?
I see two answers:
you may use unicode blank caracter (alt gr + 0160 on windows) instead of (it's the best way to triforce).
⠀▲⠀, ctrl+shift+u -> 2800 on gnome
▲⠀▲, copying caracter between thoses triangles.
simply use "mark_safe" function on your string if you want to use it as raw html without any escaping... (you may want to escape first part of the string before marking safe the whole one.)

AS3: Getting the x & y value of a matched string in a text field

I have a text field within Flash that contains a block of (obviously) text.
What I want to do is perform a search on the content of the text field that returns the x & y coordiante and the width & height of the found text. The result will be used to place a visual element over that portion of the text box.
For example:
var pattern:RegExp = /\d+/g;
var found:Array = box.text.match(pattern);
var i:String;
for each(i in found)
{
/**
* Find the x, y, width, height of the matched text in the text field
* Use result to place transparent yellow box around text
*/
}
Which visually should result in something like:
You would want to make use of the TextField class's getCharBoundaries method, which accepts character indexes and returns a Rectangle object.
As far as I know, your match method returns the strings themselves, so first you'll probably need to use the String class's indexOf method, find all your character indexes, pass them to the getCharBoundaries method, then draw some rectangles based on that output.
Here's some reference.
Good luck!