Question mark in reserved keyword - lex

I am trying to write a parser for LOLCODE GOD, WHAT I AM DOING???
(just in case to explain those strange words=) )
So, I need to have tokens for O RLY? and YA RLY.
I am trying to do like this:
reserved = { ...,
'O': 'IF_O',
'RLY?': 'IF_RLY',
'YA': 'THEN_YA',
'RLY': 'THEN_RLY', ...}
tokens = reserved.values() + (...)
t_IF_O = r'O'
t_IF_RLY = r'RLY\?'
t_THEN_YA = r'YA'
t_THEN_RLY = r'RLY'
And when I write O RLY? it is parsed like IF_O THEN_RLY and an undefined symbol ?.
If I replace RLY? with, for example, RLYY, replacing in dictionary RLY?: 'IF_RLY' -> 'RLYY': 'IF_RLY' and t_IF_RLY = r'RLYY', then it works for O RLYY.
So I think this is a problem with question marks in reserved words and do not know a workaround for this.

Sorry, but I can't reproduce this problem. Here is a working sample (ply=3.10, python=3.6):
import ply.lex as lex
tokens = (
'IF_O',
'IF_RLY',
'THEN_YA',
'THEN_RLY'
)
t_IF_O = r'O'
t_IF_RLY = r'RLY\?'
t_THEN_YA = r'YA'
t_THEN_RLY = r'RLY'
t_ignore = ' \t'
def t_error(t):
print(t)
lexer = lex.lex()
lexer.input('O RLY?')
while True:
token = lexer.token()
if token is None:
break
print(token)
And it prints:
LexToken(IF_O,'O',1,0)
LexToken(IF_RLY,'RLY?',1,2)

Related

convert amount into words in NPR format in odoo12?

I want to convert amount in words in NPR format but it always shows in Euro and cents only. How to change it to NPR format while converting into words.
I have tried all the method lang also but euro and cent cannot be replaced. My company currency is NPR but not able to convert it. I have currency_id field relating to res.currency.
I have tried code as below:
#api.depends('amount')
def set_amt_in_words(self):
self.amt_inwords = num2words(self.amount, to = 'currency', lang = 'en_IN')
if self.currency_id == 'NPR':
amt_inwords = str(amt_inwords).replace('Euro', 'rupees')
amt_inwords = str(amt_inwords).replace('Cents', 'paise')
amt_inwords = str(amt_inwords).replace('Cent', 'paise')
self.amt_inwords += '\tonly'
self.amt_inwords = self.amt_inwords.title()
I want to output in Rupees and paise.
Try
self.env.ref('base.NPR').with_context({'lang': 'en_IN'}).amount_to_text(self.amount)
The following method belongs to the model res.currency and is the responsible for translating currency amount to text (<path_to_v12>/odoo/addons/base/models/res_currency.py):
#api.multi
def amount_to_text(self, amount):
self.ensure_one()
def _num2words(number, lang):
try:
return num2words(number, lang=lang).title()
except NotImplementedError:
return num2words(number, lang='en').title()
if num2words is None:
logging.getLogger(__name__).warning("The library 'num2words' is missing, cannot render textual amounts.")
return ""
formatted = "%.{0}f".format(self.decimal_places) % amount
parts = formatted.partition('.')
integer_value = int(parts[0])
fractional_value = int(parts[2] or 0)
lang_code = self.env.context.get('lang') or self.env.user.lang
lang = self.env['res.lang'].search([('code', '=', lang_code)])
amount_words = tools.ustr('{amt_value} {amt_word}').format(
amt_value=_num2words(integer_value, lang=lang.iso_code),
amt_word=self.currency_unit_label,
)
if not self.is_zero(amount - integer_value):
amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format(
amt_value=_num2words(fractional_value, lang=lang.iso_code),
amt_word=self.currency_subunit_label,
)
return amount_words

Best way to check if variable is part of collection of enums?

I'm currently trying to port some Specman code that takes certain actions based on whether a variable is part of an enumeration. In Specman the code looks something like this:
define COMP_STATES do_add, do_sub;
define WAIT_STATES wait_X, wait_Y;
defube RUN_STATES run_X, run_Y;
type my_states : [
do_add = 3'b000;
do_sub = 3'b001;
wait_X = 3'b010;
wait_Y = 3'b011;
run_X = 3'b100;
run_Y = 3'b101;
] (bits:3);
and then later:
if(state in [COMP_STATES, RUN_STATES]){
/* DO STUFF */
} else if(state in [WAIT_STATES]){
/* DO STUFF */
}
I now would like to do this in SystemVerilog but have hit a little bit of a snag. My currently best approach uses arrays:
my_state which_state[$] = {`COMP_STATES, `RUN_STATES};
int indexes[$] = which_state.get_index( index ) where ( index == state );
int num_indexes = indexes.size(); //If state doesn't exist in my_state then the returned array of indexes will be empty.
if(num_indexes > 0) begin /* DO STUFF */ end
But there has to be a more elegant and concise way? find_first_index comes to mind but I couldn't find what it would return in case no match was found.
There are a couple of ways you could do this. If you can depend on the encoding, then you can define your collection with a wildcard and use the wildcard equality operator or inside operator
let COMP_STATES = 3'b00?; // or parameter COMP_STATES = 3'b00?;
let RUN_STATES = 3'b01?; // or parameter RUN_STATES = 3'b01?;
let WAIT_STATES = 3'b10?; // or parameter WAIT_STATES = 3'b10?;
if (my_states inside {COMP_STATES,RUN_STATES})
...
else if (my_state ==? WAIT_STATES)
...
or you could just create an expression
module top;
enum bit [2:0] {
do_add = 3'b000,
do_sub = 3'b001,
wait_X = 3'b010,
wait_Y = 3'b011,
run_X = 3'b100,
run_Y = 3'b101
} my_states;
let COMP_STATES = my_states inside {do_add, do_sub};
let WAIT_STATES = my_states inside {wait_X, wait_Y};
let RUN_STATES = my_states inside {run_X, run_Y};
initial repeat(20) begin
std::randomize(my_states);
$write (my_states.name());
case(1)
COMP_STATES, RUN_STATES:
$display("=comp,run");
WAIT_STATES:
$display("-wait");
endcase
end
endmodule
Finally, if you were starting from scratch, I would suggest looking at tagged unions and their corresponding pattern matching conditional statements

Play Scala Anorm dynamic SQL for UPDATE query

My Google-fu is letting me down, so I'm hoping you can help
I'm building some webservices is the play framework using scala and anorm for database access
One of my calls is to update an existing row in a database - i.e run a query like
UPDATE [Clerks]
SET [firstName] = {firstName}
,[lastName] = {lastName}
,[login] = {login}
,[password] = {password}
WHERE [id] = {id}
My method receives a clerk object BUT all the parameters are optional (except the id of course) as they may only wish to update a single column of the row like so
UPDATE [Clerks]
SET [firstName] = {firstName}
WHERE [id] = {id}
So I want the method to check which clerk params are defined and build the 'SET' part of the update statement accordingly
It seems like there should be a better way than to go through each param of the clerk object, check if it is defined and build the query string - but I've been unable to find anything on the topic so far.
Does anyone have any suggestions how this is best handled
As the commenters mentioned it appears to not be possible - you must build the query string yourself.
I found that examples around this lacking and it took more time to resolve this than it should have (I'm new to scala and the play framework, so this has been a common theme)
in the end this is what I implemented:
override def updateClerk(clerk: Clerk) = {
var setString: String = "[modified] = {modified}"
var params: collection.mutable.Seq[NamedParameter] =
collection.mutable.Seq(
NamedParameter("modified", toParameterValue(System.currentTimeMillis / 1000)),
NamedParameter("id", toParameterValue(clerk.id.get)))
if (clerk.firstName.isDefined) {
setString += ", [firstName] = {firstName}"
params = params :+ NamedParameter("firstName", toParameterValue(clerk.firstName.getOrElse("")))
}
if (clerk.lastName.isDefined) {
setString += ", [lastName] = {lastName}"
params = params :+ NamedParameter("lastName", toParameterValue(clerk.lastName.getOrElse("")))
}
if (clerk.login.isDefined) {
setString += ", [login] = {login}"
params = params :+ NamedParameter("login", toParameterValue(clerk.login.getOrElse("")))
}
if (clerk.password.isDefined) {
setString += ", [password] = {password}"
params = params :+ NamedParameter("password", toParameterValue(clerk.password.getOrElse("")))
}
if (clerk.supervisor.isDefined) {
setString += ", [isSupervisor] = {supervisor}"
params = params :+ NamedParameter("supervisor", toParameterValue(clerk.supervisor.getOrElse(false)))
}
val result = DB.withConnection { implicit c =>
SQL("UPDATE [Clerks] SET " + setString + " WHERE [id] = {id}").on(params:_*).executeUpdate()
}
}
it likely isn't the best way to do this, however I found it quite readable and the parameters are properly handled in the prepared statement.
Hopefully this can benefit someone running into a similar issue
If anyone wants to offer up improvements, they'd be gratefully received
Since roughly 2.6.0 this is possible directly with anorm using their macros, http://playframework.github.io/anorm/#generated-parameter-conversions
Here is my example:
case class UpdateLeagueFormInput(transferLimit: Option[Int], transferWildcard: Option[Boolean], transferOpen: Option[Boolean])
val input = UpdateLeagueFormInput(None, None, Some(true))
val toParams: ToParameterList[UpdateLeagueFormInput] = Macro.toParameters[UpdateLeagueFormInput]
val params = toParams(input)
val dynamicUpdates = params.map(p => {
val snakeName = camelToSnake(p.name)
s"$snakeName = CASE WHEN {${p.name}} IS NULL THEN l.$snakeName ELSE {${p.name}} END"
})
val generatedStmt = s"""UPDATE league l set ${dynamicUpdates.mkString(", ")} where league_id = ${league.leagueId}"""
SQL(generatedStmt).on(params: _*).executeUpdate()
producing:
UPDATE league l set transfer_limit = CASE WHEN null IS NULL THEN l.transfer_limit ELSE null END, transfer_wildcard = CASE WHEN null IS NULL THEN l.transfer_wildcard ELSE null END, transfer_open = CASE WHEN true IS NULL THEN l.transfer_open ELSE true END where league_id = 26;
Notes:
The camelToSnake function is just my own (There is an obvious ColumnNaming.SnakeCase available for parser rows, but I couldn't find something similar for parameter parsing)
My example string interpolates {league.leagueId}, when it could treat this as a parameter as well
Would be nice to avoid the redundant sets for null fields, however I don't think it's possible, and in my opinion clean code/messy auto-generated sql > messy code/clean auto-generated sql

Notepad++ conditional Macro

I'd like to search for a string starting with doi = { or url = { and then remove it from the file. For example, for the following data I'd like to remove the url and subsequently doi sections.
I don't know how I can use the replace command, as I don't know the complete string, and for Macro, how can I do this if these lines are not at regular distance from each other?
#article{Carrion2006,
author = {Carrion, M. and Arroyo, J.M.},
doi = {10.1109/TPWRS.2006.876672},
journal = {IEEE Trans. Power Syst.},
title = {{Bla Bla Bla 1}},
pages = {1371--1378},
url = {http://ieeexplore.ieee.org/lpdocs/epic03/wrapper.htm?arnumber=1664974},
year = {2006}
}
#article{Chandrasekaran2012,
author = {Chandrasekaran, K. and Hemamalini, S. and Simon, Sishaj P. and Padhy, Narayana Prasad},
issn = {03787796},
journal = {Electr. Power Syst. Res.},
pages = {109--119},
publisher = {Elsevier B.V.},
title = {{Bla Bla Bla 2}},
url = {http://linkinghub.elsevier.com/retrieve/pii/S0378779611002471},
volume = {84},
year = {2012}
}
How about:
Find what: ^(?:doi|url)\s*=\s*[^}]+\},\R
Replace with: NOTHING

MongoAlchemy query embedded documents

I want to know how to use MongoAlchemy about embeded docment operation.
But I havn't find any documents about these.
Can anyone give me some helps?
Here is demo code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from flask import Flask
from flaskext.mongoalchemy import MongoAlchemy
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['MONGOALCHEMY_DATABASE'] = 'book'
db = MongoAlchemy(app)
class Comment(db.Document):
user_id = db.StringField(db_field='uid')
posted = db.StringField(db_field='posted')
class Book(db.Document):
title = db.StringField()
author = db.StringField()
comments = db.ListField(db.DocumentField(Comment), db_field='Comments')
from mongoalchemy.session import Session
def test():
with Session.connect('book') as s:
s.clear_collection(Book)
save()
test_Book()
def save():
title = "Hello World"
author = 'me'
comment_a = Comment(user_id='user_a', posted='post_a')
comment_b = Comment(user_id='user_b', posted='post_b')
comments = [comment_a, comment_b]
book = Book(title=title, author=author, comments=comments)
book.save()
def test_Book():
book = Book.query.filter({'author':'me'}).first()
comment = book.comments[0]
comment.posted = str(book.comments[0].posted)+'_new'
book.save()
print 'change posted: Book.comments[0].posted:', book.comments[0].posted
comment_c = Comment(user_id='user_c', posted='post_c')
book.comments.append(comment_c)
book.save()
print 'append: Book.comments[2].posted:', book.comments[2].posted
query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}).limit(1).first()
print 'query type:', type(query)
if __name__ == '__main__':
test()
I want to query data which user_id is "user_c", and just return back one Comment, How can I do that?
Does these methods below are MongoAlchemy remommended? BTW, these methods will return the whole document.
#query = Book.query.filter({Book.comments:{'uid':'user_c'}}).limit(1).first()
#query = Book.query_class(Comment).filter(Comment.user_id == 'user_c').limit(1).first()
#query = Book.query.filter({'comments':{'$elemMatch':{'uid':'user_c'}}}).limit(1).first()
#query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}}).limit(1).first()
How can I change "user_c" to "user_c_new" which find by query ?
How can I remove one comment which user_id is "user_b"?
Mongo doesn't support returning subdocuments. You can use $elemMatch to filter so that only documents with matching attributes are returned, but you'll have to grab the comments yourself. You could slightly optimize by only returning the comments field as follows:
query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}})
query = query.fields(Book.comments.elem_match({Comment.user_id:'user_c'}))
result = query.limit(1).first()
print 'query result:', result.comments
Note that there was a bug with this up until 0.14.3 (which I just released a few minutes ago) which would have caused results.comments not to work.
Another very important note is that the elem_match I'm doing there only returns the first matching element. If you want all matching elements you have to filter them yourself:
query = Book.query.filter({Book.comments:{'$elemMatch':{Comment.user_id:'user_c'}}})
result = query.limit(1).first()
print 'query result:', [c for c in result.comments if c.user_id == 'user_c']