I have following code in my rails front-end html.slim file. I want to remove these nested if-else conditions. Can I implement this by moving these if-else conditions to some helper class?
- if #current_task.task_type == 'econsent'
- if #patient_organization.organization.identity_verification
- if #patient_organization.manual_verified
- if session['kiosk_token']
= render "#{#current_task.task_type}_tasks"
- else
- if #reauthenticated
= render "#{#current_task.task_type}_tasks"
- else
= render 'relogin_required_screen'
- else
= render 'manual_verification_required_screen'
- else
- if #patient.self_verified
- if session['kiosk_token']
= render "#{#current_task.task_type}_tasks"
- else
- if #reauthenticated
= render "#{#current_task.task_type}_tasks"
- else
= render 'relogin_required_screen'
- else
- if #patient.self_verification_req_sent
= render 'verify_email_after_sent_screen'
- else
= render 'verify_email_screen'
- else
= render "#{#current_task.task_type}_tasks"
I think you need to refactor those conditions, not just move them to another place. For ex: there is 5 different conditions that ends with render "#{#current_task.task_type}_tasks" you need to find what those have in comum, you don't need so many conditionals. Take a look at the usage of if, elsif, else and unless.
I believe you could simply assign an #to_render variable in your controller action, something like:
class FooController < ApplicationController
def bar_action
...
#to_render = get_to_render
...
end
private
def get_to_render
if current_task_type == 'econsent'
if #patient_organization.organization.identity_verification
if #patient_organization.manual_verified
return :relogin_required_screen if (!#reauthenticated && !kiosk_token?)
else
return :manual_verification_required_screen
end
else
if #patient.self_verified
return :relogin_required_screen if (!#reauthenticated && !kiosk_token)
else
return #patient.self_verification_req_sent ? :verify_email_after_sent_screen : :verify_email_screen
end
end
end
return "#{current_task_type}_tasks".to_sym
end
def kiosk_token?
session['kiosk_token']
end
end
Then in your html.slim file, do:
= render #to_render
I can't remember, but you may need to do:
= render "#{#to_render}"
since #to_render will be a symbol. Doing the string interpolation will automatically convert the symbol to a string.
Related
This is UCB CS61A's firt project hog 's problem5
this is wrong code(my code)
while(score0<goal and score1<goal):
if who==0 :
cur_strategy = strategy0
cur_score = score0
cur_op_score=score1
cur_op_strategy = strategy1
else:
cur_strategy = strategy1
cur_score = score1
cur_op_score=score0
cur_op_strategy = strategy0
cur_score=cur_score+take_turn(cur_strategy(cur_score,cur_op_score),cur_op_score,dice)
if(extra_turn(cur_score,cur_op_score)==False):
who=other(who)
this is the correct code(I have tested it)
while score0 < goal and score1 < goal:
if who == 0:
num_rolls = strategy0(score0, score1)
score0 += take_turn(num_rolls, score1, dice)
who = other(who) if extra_turn(score0, score1) == False else who
else:
num_rolls = strategy1(score1, score0)
score1 += take_turn(num_rolls, score0, dice)
who = other(who) if extra_turn(score1, score0) == False else who
But actually,I think these two codes are essentially same.
I don't know whether this is the problem (the quote from the project)
Only call a strategy function once per turn (or risk breaking the GUI).
I think that comes from the fact that in order to update the score0 an score1 variables, you define cur_score and update it instead. The problem is that cur_score is only a copy of the score you want to update, it is not the same object.
I am using Apache Tika 1.9 and content extraction working awesome.
The problem I am facing is with pages. I can extract total pages from document metadata. But I can't find any way to extract content per page from the document.
I had searched a lot and tried some solutions suggested by users, but did not work for me, may be due to latest Tika version.
Please suggest any solution or further research direction for this.
I will be thankful.
NOTE: I am using JRuby for implementation
Here is the class for custom content handler that I created and which solved my issue.
class PageContentHandler < ToXMLContentHandler
attr_accessor :page_tag
attr_accessor :page_number
attr_accessor :page_class
attr_accessor :page_map
def initialize
#page_number = 0
#page_tag = 'div'
#page_class = 'page'
#page_map = Hash.new
end
def startElement(uri, local_name, q_name, atts)
start_page() if #page_tag == q_name and atts.getValue('class') == #page_class
end
def endElement(uri, local_name, q_name)
end_page() if #page_tag == q_name
end
def characters(ch, start, length)
if length > 0
builder = StringBuilder.new(length)
builder.append(ch)
#page_map[#page_number] << builder.to_s if #page_number > 0
end
end
def start_page
#page_number = #page_number + 1
#page_map[#page_number] = String.new
end
def end_page
return
end
end
And to use this content handler, here is the code:
parser = AutoDetectParser.new
handler = PageContentHandler.new
parser.parse(input_stream, handler, #metadata_java, ParseContext.new)
puts handler.page_map
Let's say, for instance, I have two classes: A & B. I have set B as the handle class and would like a property from A to instantiate this class (i.e. B).
Therefore, I have done something like this in class A:
% Constructor
function a = A()
a.objB = B(); % This works fine
...
for i = 1:10
a.var(i) = B(); % This causes an error to occur
end
end
The error is listed below:
"Error using double Conversion to double from B is not possible.
The code snippet inside the for loop seems to work if I change a.var(i) = B(); to var(i) = B();.
Do you have any idea why this is?
Your .var field is probably initialized to a double when you make the assignment (maybe to []). Using a.var(i) = xxx cannot change the type of a.var.
Try resetting the value the first time it is used. EG
for i = 1:10
if i == 1
a.var = B(); % Overwrite the existing value
else
a.var(i) = B(); % Now append to that value
end
end
This will cause your a.var field to be reallocated every loop. Pre-allocated your array will make everything go much faster. The easiest way to pre-allocate is actually to just loop backwards, like this:
for i = 10:-1:1
if i == 10
a.var = B(); % Overwrite the existing value, allocated room for 10 elements
else
a.var(i) = B(); % Assign each element in turn, 9 through 1
end
end
I managed to do it, some other way.
but I have a question, I had this code before
def jumphunt(start, mylist, count = 0):
if count < len(mylist):
place = mylist[start]
print(place)
if place == 0:
return True
elif start >= len(mylist) or start < 0:
return False
move_left = (start - place)
move_right = (start + place)
return jumphunt(move_right, mylist, count+1) or jumphunt(move_left, mylist, count+1)
else:
return False
but for some reason it's not trying both ways
to get to the last item on the list.
for example: [1,2,2,3,4,5,3,2,1,7,0] and ,start=mylist[0]
it supposed to jump like this (from 1-2-4-1-left to 2-left to 5-right to 0)
but it keeps trying to go right and then index is out of range etc.
I thought that if u use return of or this or that, it will try both until it reaches True, why won't it work here?
Thanks!
Include the value you want to keep as a default parameter for the method, like this:
def my_func(int, list, i=0):
a = (i + int)
if int == 0:
return True
elif a > len(list):
i -= int
else:
i += int
int = list[i]
my_func(int, list, i)
Bear in mind that it may not even always be possible to arrive at the end of the list doing the jumping pattern you describe, and even if it is possible, this method may choose the wrong branch.
A better algorithm would look like this:
def branching_search(list, start):
marks = [0]*len(list)
pos = start
while list[pos]!=0:
marks[pos]++
if marks[pos] % 2 == 0 and pos + list[pos] < len(list):
pos += list[pos]
elif marks[pos] % 2 == 1 and pos - list[pos] >= 0:
pos -= list[pos]
else:
return False
if all(item == 0 or item > 1 for item in list)
return False
return True
This way, if it comes to an item that it has already visited, it will decide to go the opposite direction that it went last time. Also, if it comes to an item that it can't leave without going out-of-bounds, or if there is not way to get to the end, it will give up and return.
EDIT: I realized there are a number of flaws in this algorithm! Although it is better than the first approach, it is not guaranteed to work, although the reasons are somewhat complicated.
Just imagine this array (the unimportant elements are left blank):
1, 2, , 5, , , , , 5, 0
The first two elements would get only one mark (thus the loop checking condition would not work), but it would still get stuck looping between the two fives.
Here is a method that will always work:
def flood_search(list):
marks = [[]]*len(list)
marks[0] = [0]
still_moving = True
while still_moving:
still_moving = False
for pos in range(0,len(list)):
if marks[pos]:
if pos + list[pos] < len(list) and not marks[pos + list[pos]]:
marks[pos + list[pos]] = marks[pos] + [list[pos]];
pos += list[pos]
still_moving = True
if pos - list[pos] >= 0 and not marks[pos - list[pos]]:
marks[pos - list[pos]] = marks[pos] + [-list[pos]];
pos -= list[pos]
still_moving = True
return marks[-1]
This works by taking every possible branch at the same time.
You can also use the method to get the actual route taken to get to the end. It can still be used as a condition, since it returns an empty list if no path is found (a falsy value), or a list containing the path if a path is found (a truthy value).
However, you can always just use list[-1] to get the last item.
def wrap(content)
require "Nokogiri"
doc = Nokogiri::HTML.fragment("<div>"+content+"</div>")
chunks = doc.at("div").traverse do |p|
if p.is_a?(Nokogiri::XML::Text)
input = p.content
p.content = input.scan(/.{1,5}/).join("")
end
end
doc.at("div").inner_html
end
wrap("aaaaaaaaaa")
gives me
"aaaaa­aaaaa"
instead of
"aaaaaaaaaa"
How get the second result ?
Return
doc.at("div").text
instead of
doc.at("div").inner_html
This, however, strips all HTML from the result. If you need to retain other markup, you can probably get away with using CGI.unescapeHTML:
CGI.unescapeHTML(doc.at("div").inner_html)