Jump to content
The Dark Mod Forums

Ungoliant's mapping questions


ungoliant

Recommended Posts

Link to comment
Share on other sites

another probably very basic python question.

how do these visitor classes understand what the 'node' parameter is in pre/post functions? i get the self part, its passed implicitly in constructor, i guess. theres other pre/post functions for other visitor types that use seemingly arbitrary parameters, which I don't really get.

Link to comment
Share on other sites

Python doesn't have any restrictions on data types for function arguments. It's up to the programmer to give a function the right type of argument, to document it, and to name the variable something that gives the user a clue. If you were to pass a different type of object to the ScreenNodeVisitor class' pre() function, it would error during run time at the first point where that function tries to call a node method on the object that gets passed to it. Unlike statically-typed languages, Python won't give you an error at compile time.

 

Python automatically adds the identity of the instance ('self') to any instance calls. If you write:

 

class MyClass:

...

myInstance = MyClass() # calls constructor

myInstance.doSomething(anArg)

 

The last line is equivalent to the static function call:

MyClass.doSomething(myInstance, anArg)

 

Hence why doSomething() takes two args: (self, anArg)

 

In the case of these Visitor classes, each is meant to be used with a particular object's traverse() method, or another method specifically provided for the purpose. A ScreenNodeVisitor gets passed to the object returned by GlobalScreenGraph.root() (a ScreenNode, I should think). Whoever created the API decided that ScreenNode would have a method traverse() that takes a Visitor as argument, and that'll pass a node object to that visitor's pre() method. As long as the user follows those rules, it'll work as expected. If you pass something different, you'll get a NameError when the script tries to access a node method.

 

The other examples, like the one that takes a key-value tuple as arguments, are meant to work with specific functions too. The EntityVisitor class has a visit() method that takes a key-value pair of arguments, and ScreenNodes have a method forEachKeyValue() which iterates through their spawnargs and passes each pair of values to the visit() method of the object that they get passed as an argument. So yes these class methods can take any type of arguments, but it's not completely arbitrary because you design your visitor class to work with a particular recursive function, and whoever writes that function decides what methods and arguments its visitors should have.

 

One more note: The DR API is well designed, but it's a short bridge between the underlying C++ code and python, and it shows. The "pythonic" way of doing things has no use for casts between derived data types for example, whereas the DR API requires you to explicitly cast a ScreenNode to a subclass with functions like ScreenNode.getBrush(). So bear that in mind when things don't seem to make conceptual sense -- we're operating in a zone somewhere between two very different programming paradigms, and features of both show up.

Edited by SteveL
Link to comment
Share on other sites

having some issues with the python workflow i've set up. i'm using notepad++ for editing and running python programs with a command i saved as a shortcut, which is

pythonw "$(FULL_CURRENT_PATH)"

i'm having problems with this now for creating files with open("mystuff.abc", "wb"). I've tried running my .py file in notepad++ with that command while it was located on desktop, and c:\stuff, and i always get this error:

IOError: [Errno 13] Permission denied

if i just run the interpreter by itself and do the same thing, it works fine and writes the file to d:\python27 which is my python install directory. i'd like to be able to run my shit from whatever working directory my .py file is at from notepad++. any hints on whats going on with the permissions here?

 

edit: found this on stackoverflow:

the working directory inside a script is the location you ran the script from, not the location of the script. If you run the script from elsewhere (maybe the script is in your system path) the relative path to the subdirectory will not work

does that mean its trying to write the file at C:\Program Files (x86)\Notepad++ ???? and is that even illegal?

 

re-edit: os.getcwd() yields C:\Program Files (x86)\Notepad++, still don't understand why its illegal to write a file here. also, would like to get back to a relative path to the .py file to write to. not sure how to do this

 

re-re-edit: nevermind the whole damn thing, figured it out.

open(os.path.dirname(__file__) + os.sep + 'mystuff.abc', 'wb')

Edited by ungoliant
  • Like 1
Link to comment
Share on other sites

trying to do more python stuff. hard to google this because i don't even know the technical term for what i'm looking for.

basically, i want to sort a list of strings. but I don't want to sort it starting at the first character. i want to sort it based on a substring starting after the 2nd whitespace character. i have no idea how to implement something like this.

Example list:

5935345 N Butt St
32 S Butt St
1232 W Widget Way

even better would be an additional way to remove the direction of the street from the equation entirely, like if everything between 1st/2nd whitespace delimiter is only 1 character, ignore and sort starting after the next whitespace, otherwise sort it as is.

 

Basically I'm not sure how to work with relative char positions in strings, or how to sort based on char position

 

edit: i think i found the way to obtain the key i want to sort by for each string

target = myString.rpartition(' ')[0]

should return the 2nd to last segment of characters as a string

 

so now, the thing is, how the crap do i sort a list of dictionaries by the key 'address' where the value of that key in each dictionary is some random string in address format, but the value i want to sort by is the substring of that string as derived above? I can't figure out how to use sort() to do this.

Do i need to write my own sort function, or am i missing something?

Edited by ungoliant
Link to comment
Share on other sites

thanks for this. list comprehensions were introduced as a sort of post-script of this newbie python challenge i'm doing as part of a possible sort solution, but i'm still having problems wrapping my head around them, and the utility they can provide in different situations.

 

Also, about this:

 ordered = wordlist[2:] + wordlist[:2] 

the whole [2:] thing with the colon. what is that thing even even called. Sometimes I understand how its being used and other times I don't. I know it can be used for precision and other stuff, but I really need to look it up and just read on it.

 

Lastly, about flip sort flip code. There was explained after the challenge about ways to do this sort of thing without writing independent functions, or maybe i understood it wrong. something about sorting with like lambda keys, like stuff.sort(key = lambda, a: doStuff(a)) or something like that. Completely lost on that. no idea how this works, and the sort() documentation in the standard library on the subject is greek to me.

Link to comment
Share on other sites

The [2:] thing is called slice notation. You use it for getting subsections of a string or list of items. It's straightforward but not obvious. NB both strings and lists etc start their numbering at 0, so the first char or item is 0.

 

'Hello'[1:2]

returns 'el', characters 1 and 2 of the string.

When a digit is missing from the slice, it just means unlimited. So

 

'Hello'[:2] is the same as 'Hello'[0:2] and returns 'Hel'

'Hello'[2:] returns 'lo', everything after character 2.

 

In general, you can split a string or list by putting the same number in two halves of a slice. Rich's script splits your four-word strings into lists of individual words, then moves the last two to the front to sort them, sorts them, then puts the words back in their original order.

 

You can specify your own sort function either as a normal function or as a lambda (which is just a shortcut method of defining a 1-line function without giving it a name). The value to be sorted is passed to your function, then the return value of the function is used for the sort instead of the original key. Made up example using both methods:

 

nums = [1,2,-3]

sorted(nums) # returns [-3, 1, 2]

 

def absolute(n):

return n if n>=0 else -n

 

sorted(nums, key=absolute) # returns [1, 2, -3]

 

Because the absolute() function is a one liner, you can choose to define it right there in the function call using lambda syntax instead of defining it elsewhere and giving it a name:

 

sorted(nums, key=lambda n: n if n>=0 else -n)

 

That's exactly equivalent to the method with the separate function definition.

 

Edit: sorry about the (lack of) formatting, wrote this from my phone on a break!

Edited by SteveL
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recent Status Updates

    • Ansome

      Finally got my PC back from the shop after my SSD got corrupted a week ago and damaged my motherboard. Scary stuff, but thank goodness it happened right after two months of FM development instead of wiping all my work before I could release it. New SSD, repaired Motherboard and BIOS, and we're ready to start working on my second FM with some added version control in the cloud just to be safe!
      · 1 reply
    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
×
×
  • Create New...