Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 305 306 [307] 308 309 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 906712 times)

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #4590 on: July 03, 2013, 08:21:07 pm »

I'm confused by what you mean. @_@
I don' think I ever said it was a problem with ++, but rather it's a sideeffect of the undefined execution order of functions passed as arguements D:
Or that's what I meant, but it didn't make its way into the post.
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

MrSparky

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4591 on: July 03, 2013, 09:10:00 pm »

Actually Sky, that's not due to differences in ++. You can replace counter++ with Foo() where Foo() is defined as
Code: [Select]
string Foo()
That made me think of Mr. T programming something. Maybe a program that calls anyone a Foo' if they encounter a bug.
I pity the Foo' who don't sanitize his inputs!
Logged

MadocComadrin

  • Bay Watcher
  • A mysterious laboratory goblin!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4592 on: July 03, 2013, 10:11:03 pm »

I read this when it was posted a few days ago.

On the one hand, C++ is fast. On the other hand, basic operations that work in just about every other language ever can lead to undefined behavior. That's a good trade-off, right?
C/C++ wasn't designed by people who prefer speed over correctness, they were designed by people who expect others to create correct code. If you type the wrong code in assembly, you don't complain when the assembler doesn't correct it for you. Jeez
I fail to see how the differential engine anecdote is relevant (Incidentally, someone over there used the same example). There is a difference between putting in obviously bad data and data that appears correct to someone who doesn't spend all day reading about sequence points on Wikipedia.
The point to take from that is that procedural languages can only do what you tell them, and you shouldn't expect a language or compiler to understand what you want done--make sure it's done the way you want it to be done.

Knowing operator associativity and evaluation, as well as knowing some of the more general tidbits about a language beyond simple paradigm information is responsible programming, likewise, a little bit of study of the organization of programming languages could easily pickup when and why (or at least a few possible whys) certain expressions (especially those composed of terms separated by operators of equal precedence) end up evaluated right-to-left instead of left-to-right. It could be the parser, or how arguments are put on the stack, or both! You don't have to spend all day on Wikipedia to learn this stuff, but you do have to understand it if you want to trade in the moniker of "Amateur Programmer" to "Computer Scientist/Professional Programmer"--ESPECIALLY when it comes to nuanced operators such as postfix++.   
« Last Edit: July 03, 2013, 10:12:34 pm by MadocComadrin »
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4593 on: July 04, 2013, 03:11:44 am »

SQL question.
So I've been meaning to ask you guys if a solution I came up with is actually an anti-pattern (or whatever term the cool kids use these days) or can be improved in some way.

The situation:
I have a RBAC system, that hierarchical trees of "stuff you can do". It's really fine grained, so every CRUD operation has its own "Action", those actions are grouped into Tasks, and Tasks into Roles. Except for being in that strict hierarchy, there's no real difference between those three. Then I have a table where users are assigned one or more Roles, and then want to know if that user has access to a certain action.

This "can I see/do X" can be called multiple times in a pageview, so what I needed was a way to read really fast through a tree, to see if one of the branches/leaves matches an item X. Writing to the tree may be expensive, as that won't happen often.

A solution: After some searching I found Closure Tables (http://www.slideshare.net/billkarwin/models-for-hierarchical-data, Start at page 40) to be the closest match to what I need. However, my data implies that a certain branch can be included in the same tree multiple times in different locations, something that the Closure table does not provide for. So I modified it as such:
To the Paths table I added a field "length". This field has only three significant values: 0, 1, many. This will allow me to add multiple tree branches to a tree, and delete the correct one if I delete it again (this was a problem with the original closure table, as you wouldn't know the location of the particular subtree you deleted was in).

I now have three tables:
access_right contains the combinations of userid and roles
access_item contains the RBAC items
access_path contains the hierarchy of the access_items.

Now I can use the following SQL commands:

To see if user ":userid" has access to action ":itemname" (this one is called many times):
Code: [Select]
SELECT id FROM access_item i WHERE i.name LIKE :itemname AND i.id IN
(SELECT p.descendant FROM access_path p WHERE p.ancestor IN
(SELECT r.role_id FROM access_right r WHERE r.userid = :userid )
OR p.ancestor = (SELECT u.id FROM access_item u WHERE u.name = 'Default')) LIMIT 1
The last part makes sure that if an action is assigned to the "Default" role everyone will always have access to it.


To add a child/subtree to a tree/item first check if there is no loop using the above statement. Then loop over the entire subtree you want to add and do the following (:parentid is the element we're adding to, $child is the element (top of the subtree) we're adding).
Code: [Select]
$grandChildren = AccessPath::model()->findAllByAttributes(array('ancestor' => $child->id)); // Gets an array of all Path items that have $child->id as an ancestor, including $child->id itself).
foreach ($grandChildren as $grandchild) {
INSERT INTO access_path (ancestor, descendant, length)
SELECT ancestor, :childid, (length+1+{$grandchild->length}) FROM access_path
WHERE descendant = :parentid
}
This code adds a path for every descendant of "child" to every ancestor of "parent" with the correct length.

Deletion is a bit more complicated than in "normal" Closure tables as we now need to make sure that we delete only one reference from all ancestors to all descendants, and specifically one from child to parent where the length is "1".
This is actual code instead of pseudo, also because I hope my comments are good enough for someone who has not worked with this framework to understand. We're now removing a "Child" item from a "Parent" item, which means removing an entire tree. The array param in "execute" replaces the strings (like :pid and :cid) in the SQL with the values of the variables, in a safe way.
Code: [Select]
// The Ancestors of the Parent item (including parent item itself
$ancestorIds = AccessPath::model()->getCommandBuilder()->
createSqlCommand("SELECT ancestor FROM {$this->pathTable}
WHERE descendant = :itemid", array(
':itemid' => $item->id,
)
)->queryColumn();
// The Descendants of the child item (including child item itself
$childIds = AccessPath::model()->getCommandBuilder()->
createSqlCommand("SELECT descendant FROM {$this->pathTable}
WHERE ancestor = :childid", array(
':childid' => $child->id,
)
)->queryColumn();
// Now, remove exactly ONE reference from every child item to every parent item
// Prepare statement (Prepared statements are a lot faster)
$comm = AccessPath::model()->getCommandBuilder()->
createSqlCommand("DELETE FROM {$this->pathTable} WHERE ancestor = :pid AND descendant = :cid AND length > 1 LIMIT 1");
foreach ($ancestorIds as $pid) {
foreach ($childIds as $cid) {
// At the direct connection, make sure the "length" property is 1, so we have the right one
if ($pid == $item->id && $cid == $child->id) {
AccessPath::model()->getCommandBuilder()->
createSqlCommand("DELETE FROM {$this->pathTable} WHERE ancestor = :pid AND descendant = :cid AND length = 1 LIMIT 1")
->execute(array(':pid' => $pid, ':cid' => $cid));
;
} else {
$comm->execute(array(':pid' => $pid, ':cid' => $cid));
}
}
}
Edit: The reason the DELETE statement can't be done in a single uber-statement is the "LIMIT 1" requirement. I need only to delete one of each unique combination, and there's no way to do that in MySQL as far as I know, it will delete all matches.


Question: It seems to be working, but am I making any obvious mistakes here, doing something completely wrong, or can this be improved in any way?
« Last Edit: July 04, 2013, 03:44:01 am by Siquo »
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

MrSparky

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4594 on: July 06, 2013, 11:22:44 am »

I finally have a new programming project to work on. I'll be creating a computer version of BattleCry, a civil war battle boardgame published by AvalonHill and Hasbro in 2000. I will obviously not distribute it except to my uncle since it was his idea. Both because I'm barely a novice coder and because I don't know shit about copyright.

I'm currently in the design phase. Even just scribbling I see I'll need to do a shit tonne of stuff I haven't done before. It'll be a good journeyman piece.
I haven't done anything graphical before.
My first thought of how to implement a hexagon board involved wasting half the memory allocated.
I haven't done anything with networking.
I haven't done any AI.

This is the largest project I've ever started. The next largest was probably the tic-tac-toe state tree.
Logged

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4595 on: July 06, 2013, 12:05:28 pm »

I finally have a new programming project to work on. I'll be creating a computer version of BattleCry, a civil war battle boardgame published by AvalonHill and Hasbro in 2000. I will obviously not distribute it except to my uncle since it was his idea. Both because I'm barely a novice coder and because I don't know shit about copyright.

I'm currently in the design phase. Even just scribbling I see I'll need to do a shit tonne of stuff I haven't done before. It'll be a good journeyman piece.
I haven't done anything graphical before.
My first thought of how to implement a hexagon board involved wasting half the memory allocated.
I haven't done anything with networking.
I haven't done any AI.

This is the largest project I've ever started. The next largest was probably the tic-tac-toe state tree.
That's a large step you're taking there buddy. Which language are you using?
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4596 on: July 06, 2013, 12:28:40 pm »

I finally have a new programming project to work on. I'll be creating a computer version of BattleCry, a civil war battle boardgame published by AvalonHill and Hasbro in 2000. I will obviously not distribute it except to my uncle since it was his idea. Both because I'm barely a novice coder and because I don't know shit about copyright.

I'm currently in the design phase. Even just scribbling I see I'll need to do a shit tonne of stuff I haven't done before. It'll be a good journeyman piece.
I haven't done anything graphical before.
My first thought of how to implement a hexagon board involved wasting half the memory allocated.
I haven't done anything with networking.
I haven't done any AI.

This is the largest project I've ever started. The next largest was probably the tic-tac-toe state tree.
That's a large step you're taking there buddy. Which language are you using?

((please don't say C))

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #4597 on: July 06, 2013, 12:34:00 pm »

(Lisp! Lisp! Lisp! Say Lisp!)
(Or assembly x86!)
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4598 on: July 06, 2013, 01:41:06 pm »

(Lisp! Lisp! Lisp! Say Lisp!)
(Or assembly x86!)

((get back in your box and don't come out unless we tell you to))

((besides x86_64 asm is clearly better))

GlyphGryph

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4599 on: July 06, 2013, 01:48:12 pm »

(Lisp is the best language, say Lisp!)
Logged

alway

  • Bay Watcher
  • 🏳️‍⚧️
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4600 on: July 06, 2013, 02:03:42 pm »

Befunge is the most fun because it is done in 3 or more dimensions (the Bequnge environment lets you code in 105 dimensions). And is self modifying.
Logged

Dutchling

  • Bay Watcher
  • Ridin' with Biden
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4601 on: July 06, 2013, 02:04:35 pm »

Err... this is not really a coding problem, but it has something to do with Linux so I think this should be the correct spot ;)

I just want to know if I'm just not seeing something extremely obvious or if there is actually something wrong.
I cannot open a file with a program (which has no problem opening said file types) as it 'cannot locate it' even though it should be there. Just see the pic:
Spoiler (click to show/hide)
I don't want to ask this on the official forums until I'm sure I'm not being an idiot :x
« Last Edit: July 06, 2013, 02:36:58 pm by Dutchling »
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4602 on: July 06, 2013, 02:19:51 pm »

There is an issue with your image.

Dutchling

  • Bay Watcher
  • Ridin' with Biden
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4603 on: July 06, 2013, 02:37:14 pm »

Should be resolved now.
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #4604 on: July 06, 2013, 02:38:27 pm »

What's the output from ls?
Pages: 1 ... 305 306 [307] 308 309 ... 796