?

Log in

naming my racist elf

Ari told me a trick he uses as a GM for naming NPCs: pick a language to be thematic, type words into Google Translate, use. So one NPC is Hungarian or something for "Betrayer", and is intended to backstab the PCs at some point, and the players have no clue.

Neat trick, but one not relevant to most of my PCs these days, where I expy some anime heroine and don't try to hide my work. (Latest: Kyouko the Dungeon Slayer, an adaptation of Sakura Kyouko.)

But someone was recruiting for an all-evil PbP game, which isn't my usual thing, but I got tempted to try to think of something anyway, It's D&D3.5, so I figured I'd start with a druid, for maximum mechanical cheese. Evil druid? Sure, he wields the power of nature for evil. Or he wields the power of nature, and is a selfish jerk. If you want philosophy, you can talk about predator/prey, nature red in tooth and claw, social darwinism.

Race? (Meaning species). I like elves as an idea, but have been avoiding them, because a 1st level 100 year old character just hurts my head. But for the character I was forming? The guy who can feel superior because he lives 10x longer than you is a perfect fit.

And even better, there's the gray elf subrace, with +2 Int. Literally smarter than you. (D&D swaps gray and high elves from Tolkien: "high elves" are like the Sindar default, gray elves the longer-lived and smarter and more arrogant 'Noldor'.)

Great, a racist gray elf druid! What to name him? I tried thinking of 'elvish' names on my own, but wasn't getting far. (I hate coming up with names.) Time to try the language trick! What are elvish languages? Tolkien was inspired by Welsh and Finnish, Order of the Stick uses pseudo-Latinate names. I started with Welsh. What's a word? Well, 'racist'. So I type that in... and get 'hiliol'.

Hiliol the elf. I dunno about you, but I figured I was done on the first try. Feels vaguely elvish, doesn't have an obvious gender. (I was figuring I'd go for androgyny, a la Vaarsuvius in Order, though he's since become male -- trying to improve the human stock by fathering lots of half-elves. But anyway.)

That was a stroke of luck, really; I've since tried some other words, and they translate to words that are so flagrantly Welsh as to be intrusive. Like 'twyllwr' for "deceiver" or 'celwyddog' for "liar". (Hiliol's Big Crime was fraud, trying to convince foolish humans that he could give them elven lifespan.)

Finnish could have worked, its 'racist' is "rasistinen", though I just realized it sounds like an import of 'racist', so maybe not.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/466891.html#comments

Tags:

I hate whiteboarding

(Definition: solving a problem or writing code in an interview, in front of people, under time pressure. Video/online counts as well.)

I'm not sure I've gotten much better at this in the past year. It's one thing if the problem is one I already know and I just have to write code; I think I regurgitate under pressure fairly well. But if I have to really think about the problem then it feels like my IQ drops 20+ points under stress and being stared at. And when I come up with one idea for a solution, it's hard to try to think of others that might be better in some sense -- after all, the clock is ticking, and I have to start writing code! Not to mention the fun of having to write correct code without backup documentation or a compiler -- my memory prioritizes the stuff that's hard to look up, like What You Shouldn't Do, or Where Information Is, over the stuff that's trivial to look up at need.

As for actually being creative, that goes a lot better when I have time to relax, or step away from the problem and not consciously think about it. A lot of my best solutions just come to me when doing something else, or musing in bed or the shower, or walking.

Post prompted by Thursday's experience, where I was asked to construct a relative path between two directories, and I saw it as a tree problem and hared down making C++ trees with nodes and everything. At the end I asked how I'd done, and was told "well, this works, or would work with a bit more polishing of the code, but there's a simpler way with just lists." One minute after leaving the building I saw what that would be, and at home it took me 18 minutes to code and debug, which I e-mailed in, but apparently got no credit for that.

I did better Monday, with some basic linked list questions; that rejection was "you did well and seem a fine technologist, but not commercially experienced enough". Which is back to the Catch-22 of not being able to get experience because I'm not experienced enough.

On the flip side, Wednesday had a video interview where I had no idea how I did, but they want me to go to NYC for an onsite next week. So yay, progress... of course, that'll probably be more whiteboarding.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/466483.html#comments

JavaScript quirks

I've started studying JavaScript a bit, as you might guess from recent posts. It's struck me as a mix of Perl, Python, and crack. It's got some neat things, especially in comparison to one language or the other. And it's got lots of... wtf things.

+: exponentiation operator; nested arrays and objects (dictionaries) (without Perl's references); first class functions and lambdas and closures, including nested functions (unlike Perl); Perl-like push/pop/shift/unshift array operators (but what's the performance?); consistent 'valueOf' and 'toString' methods; JSON; multiple kinds of for loops; Perl style labeled break and continue; some convenient conversions (but see below); nice Date methods.

-: oh boy.

* JSON stringifies nested structures nicely, but simple output doesn't: [1, [2,3]] outputs as [1, 2, 3].
* (object1 == object2) is always false, no matter the underlying values. This holds for arrays and Date objects too. Nothing like Python's structural equality, or even that of STL containers.
** But you can do *inequality* comparison: ([1,2,3] < [2,2,3]) == true.
* strings take negative indices a la Python, but arrays don't.
* there's a typeof operator, but it just says 'object' for arrays.
* "5"+2 == "52" (convert 2 to "2", concatenate), but "5"-2 == 3 (convert "5" to 5, subtract.) And no Python string multiplier like "a"*2 == "aa".
** As Avi noted, it gets even weirder given that the values could be hidden in a variable. a+2=="52", a-2==3
* [1,2]+[3,4] doesn't concatenate arrays, doesn't add by element, doesn't give a type error, but gives... "1,23,4" (turn arrays into strings, concatenate without delimiter.)

My friend Mark linked me to https://www.destroyallsoftware.com/talks/wat which gives some more:
* []+{} == [object Object]
Ok, addition is commutative, right?
{}+[] == 0
And for luck: {}+{} == NaN
As above, []+[] == ""
** Actually, on playing with typeof, I think those are actually all strings. "[object Object]", "0", "NaN". OTOH, {}+[4]+5 == 9 (but typeof string)
**
>>> 5+{}+[4]
5[object Object]4 // because of course it does
*
return
  x;

turns into
 return;
 x;



* All numbers are 64-bit floats; you can still bitshift them, but as integers, so 5.2 << 2 == 20. This makes more sense when I remembered that floats are weird, not integers+fractions, so a simple bitshift of the fraction wouldn't make sense.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/466385.html#comments

Hoisting Shadows

A bit after writing the previous post on shadowing variables in JavaScript, I came across this page on hoisting. JavaScript re-writes your code so that declarations but not initializations to the top of current scope, meaning the script or function[1]. So

console.log(a);
var a=5;


turns into

var a;
console.log(a);
a=5;


Put that way, it's clear why the problem happens, if not why the language was designed this way.

Does the same thing happen in Python? Searching did not get clear results. I saw pages contrasting JavaScript with Python, which doesn't even *have* declarations. OTOH, the same behavior occurs. So... I dunno.

[1] JavaScipt does not have block scoping the way C and Perl[2] do; scopes are delimited by curly braces, but random curly braces do nothing to isolate variables.

{ a=5; }
console.log(a);


will work just fine. :(

[2] As I was verifying this in Perl, I ran into behavior I'd forgotten. I'd thrown in "use strict;" but wasn't getting the errors I expected. Eventually I recalled that $a and $b have special meaning in Perl (I think for comparison functions), and I guess are pre-declared, and I was using $a a la the above code, so strict didn't complain about trying to access $a before assigning to it. Sigh.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/465980.html#comments

Shadows of JavaScript

Months ago, Robbie had found this scoping problem in Python, which I reduced to essentials.

I've started finally learning JavaScript, and it has nicer lambdas than Python, and proper hiding of nested functions unlike Perl. But it has the same scope problem:

g1 = 12;
function func() {
  document.getElementById("demo").innerHTML = g1;

  var g1 = 5;

}
func();


(I'm not including the HTML framework because DW/LJ would yell at me if I did.)

Output is 'undefined', rather than 12. As in Python, the local variable further down shadows the outer scope variable (doesn't matter if the "g1=12" has a 'var' before it) even for lines before the local variable.

As mentioned before, Perl has proper lexical scoping here (though not for nested functions.) I don't think I can even create similar code in Scheme/Lisp, where the scoping is explicit with parentheses. (There's 'define' but I think that makes a new global, and it didn't work.) In Ocaml I have

let g1="10";;

let func () =
  print_endline g1;
  let g1="cat" in
    g1
  ;;

func();;


Which I suspect is as explicit as Lisp parentheses, in its own way; the print line is obviously outside the following "let ... in...".

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/465845.html#comments

PC parents

If I ever GM an RPG of my own, I think I'll ask the players to give some indication of their parentage or how they were raised. Doesn't have to be detailed, maybe not even named, but something about where they're from and who raised them. Everyone has parents, or some substitute, after all, rather than springing out of the mists. And no amnesia card allowed.

(This is partially stimulated by Nanoha A's, my biggest gripe regarding which is the total lack of explanation of how Hayate is living alone as a 9 year old. If parents died recently they're never mentioned, if they died when she was a baby... who raised her and taught her stuff?)

But then I wonder, would I be being hypocritical? Have I done this for my own PCs? Answer seems to be "I didn't, but now I do." And I'll chronologically list my PC backgrounds. If you find that boring, which is understandable, you've been warned.

Read more...Collapse )

So if you bother reading all that... the answer is yes, I do do it more, though the increase hasn't been monotonic. Kind of depends on my inspiration and the nature of the game: some inspire or require more effort than others. In particular I've gotten pretty pessimistic about the lifespan of a random play-by-post (PbP) game, and am not inclined to put too much effort into them. The Yona characters were earlier... though I also like adapting Yona to various settings. Might help that the original character is "medieval", unlike Hayate or Diane.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/465443.html#comments

Tags:

fast array rotation

A simple problem I'd never had occasion to think much before, before I saw a sample coding problem.

How to rotate the elements of an N-element array by k spaces? An obvious way is to shuffle it one space, k times, but that's slow, O(N*k). Faster, which I saw about as soon as I thought about performance, is to use a second array B, where B[(i+k)%N] = A[i]. But that takes O(N) extra space. Can you do better?

Yes, as I realized at 5am. For each element A[i], move it to A[(i+k)%N]. O(N) time, O(1) extra space. Can't beat that!

Except some mildly tricky math intervenes: the natural approach only works if N and k are relatively prime. A more general solution is

let g = gcd(N,k)
for i in [0,g)
  for j in [0, N/g)
    shuffle element k spaces


Despite looking like a double loop, it's still O(N), with g*N/g iterations.

I've also learned that C++ has a gcd function now. std::experimental::gcd, in the header experimental/numeric. C++17 moves it out of experimental but even g++ isn't doing that by default.

The really annoying this is that this is the sort of solution that comes naturally to me lying in bed, with little conscious effort, but that I'd likely fail to get in a whiteboard session or timed coding test, due to stress dropping my working IQ.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/465263.html#comments

Moana

Saw it this afternoon. Fairly good. Or at least it had catchy songs (if not as catchy to me as Frozen) and I teared up a few times, so it does the job of a good Disney musical-movie. I did wonder about the response of native Hawaiians or Polynesians to some of the cultural depiction. Checking Wikipedia... the main criticisms there are about the lack of a strong goddess, and Maui being an "overweight" buffoon. So "culture is okay, but the gods weren't." Also controversy about a costume.

Absolutely no romance, even less than in Brave.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/464968.html#comments

Tags:

Applying A*

I've played a lot of freeciv and freecol over recent years. Both games let you order a unit to go to some square, and hopefully it takes the fastest route there. The 'world' is a square grid, of various terrain types and associated movement costs -- e.g. plains or desert take 1 move, but mountains take 3; roads and rivers take 1/3 no matter what terrain type they're laid over.

A* is this sweet magic algorithm for finding shortest paths in some graphs efficiently, vs. doing breadth-first search in all directions, but I was having trouble applying it mentally. I was using the common Manhattan distance heuristic, h((0,0),(x,y)) = x+y, and I wasn't getting good results: the algorithm would cheerfully march down a straight plains path to the goal, while ignoring a path that might step away and into mountains, but then ride a river to the goal much faster.

So I backed off, and thought about BFS. I realized that would work better if instead of naive BFS, enqueuing grid squares as you found them, instead you ranked them by total travel time so far. This is basically A* without a heuristic. Instead of exploring all paths N squares away, you'd explore all paths N moves away; it would still be radiating in all sorts of directions, but at least you'd find the shortest path to the goal.

Then I realized I'd been using the wrong heuristic; the right one should be the shortest possible journey. Or as WP says, "it never overestimates the actual cost to get to the nearest goal node." So the heuristic in this application has to consider rivers and roads, such that h() = (x+y)/3, not (x+y). This works much better: the plains march looks less attractive as it advances, converting cheap heuristic moves into actual plains moves, and the "mountain and away" move gets a chance to be considered.

Actually, units and roads can go diagonally, though rivers are rectilinear, so the proper heuristic is h((0,0),(x,y)) = max(x,y)/3.

Actually actually, infantry units only have one move, but are still guaranteed one square of movement per turn, so can march across mountains as easily as across plains; it's mounted units, with e.g. 4 move in freecol, that really care about base terrain type. Also fractional movement can be useful, e.g. I think a unit with 2/3 move left (after moving on river) can still move onto an adjacent plains.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/464671.html#comments

Headphones! 2

Ari, one of my hosts, said the other night that my (Panasonic) phones must be really good, that he'd been yelling at me from the kitchen and I didn't hear them. I don't know if he could have been yelling that loudly, but they certainly obscured something. And they're working pretty well now, there are Fanw and two kids six feet in front of me, and a bunch of gamers 10 feet away, but mostly I hear Christopher Franke.

If nothing's playing then there's some attenuation but not much blockage, not as much as earplugs, maybe. But with sounds, I mostly hear the sound.

Maybe I'm playing it too loudly. But that seems unlikely, I've never been a high volume guy. One of those people cursed with sensitivity to faint sounds, physical flinching from loud ones, but impairment in understanding speech...

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/464425.html#comments

so many homophones

As I enter Japanese words, sometimes I mess up, or am guessing at what I hear in anime. I've noticed that almost anything I enter still has a meaning according to my tools. And words with the same pronunciation seem more common than in English.

As W reminded me, Japanese doesn't have that many syllables. There are about 50 basic syllables, maybe 80 including the compounds like 'gyo'. At 50, there are 2500 pairs, and 125,000 triplets. Even a large vocabulary can fill up most of that. By contrast, I read once that English has over 1000 syllables, which means 1 million pairs, and 1 billion triplets. Mind you, many of those won't be pronounceable, or valid under English phonotactics, or distinct[1]. But still, lots of words -- even 99% discounting would mean 10 million triplets.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/464294.html#comments

Tags:

Headphones!

Have I talked about this before? Feels like I might have, but don't see anything in the past few months. I use earbuds a lot, to play music at home, or of course out and about. I've gone through a lot too, as they kept failing in one ear or the other, especially after being carried in my pocket for a while.

I remembered Panasonic as being a solid brand for electronics, looked up online and saw that they do make earphones -- though none sold in local stores -- and ordered three, figuring even Panasonic couldn't prevent thin wires from breaking. $10 each, supposedly good performance, certainly fine by me.

Aaaand I may have outsmarted myself, I'm still on the first set. Granted I was protecting it more, putting it in a ziploc bag before pocketing it, largely to reduce tanglement but presumably also reducing friction. But I lost the bag at some point, and it's still working.

I actually have five sets. One I'd bought earlier, the three Panasonics, and one we found on the floor of Grendel's one night and no one claimed. I also had 3 $1 sets I got from Dollar Tree, but they smelled so strongly once I opened the packets that I got paranoid about touching ultra-cheap Chinese products, and I think I threw them out.

Technically all the ones I have are in-ear, so they stay in better and there's more noise isolation, especially from the Panasonics.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/463893.html#comments

Really bad typo

Typos happen. Usually they don't change meaning too much. But I just caught one of my worst ever: I looked back at e-mail with W about meeting up for something, and where I meant "That works for me", I'd sent "That's work for me". I am mortified, and worried she's been feeling hurt the past couple days.

Re-reading is your friend. And your friends' friend.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/463788.html#comments

Tags:

Notes to diary keepers

Date your entries. "When did I write this?" can be a fun detective exercise but not in the aggregate.


Fully date your entries. Yes, it's annoying to write the year all the time, but much later, when paging through (paper or textfile), you'll thank yourself for not having to find the beginning of year marker, assuming you left one.

If you have multiple diary books, putting the date range on the covers is nice too.

***

I found a book split between my USSR trip in 1991 and life notes in 2001-2002. Very frugal of me but makes the diary hard to order. Thanks, me.

A bunch of my diaries actually have class notes in the front, diaries in the back; school year ends without filling the notebook, so there was spare space...

***

On the electronic front, my journal files have a format of

{{2014 Dec 3}
life stuff
here

{special event like Arisia
whole bunch of lines
}
}

Not exactly sophisticated, but allows pretty free-form entry, while delimiting entries on characters you can %-bounce on in vi, while also not competing with the parentheses one might normally use (including smiley face parentheses, which don't close). And yes, I have a script somewhere that checks for mismatched curly braces. I designed the date header with some idea of easing parsing by simple scripts, though it hasn't come up much.

As you can see, the braces recurse, so I can group logically connected paragraphs within a day's entry.

One could obviously make the format smarter, with tags, or {{event} stuff}, but even what I have has been pretty helpful. I can find a day's entry quickly, beginning and end, and see the bounds of long sub-entries. There are ad hoc tags: "book:" at the beginning of a line for books I might want to read; "movie:" at the beginning for movies I've seen (yes, not very consistent); semi-regular tags for regular social events, to enable searching for those; "me on " for links to stuff I write elsewhere. Could be better though, like having an index at the top of such tags for standardized use.

In theory I could write a script to bound searches, e.g. looking for regexes within entries of a certain date, basically primitive database functionality. (Or you could put entries in a real database, but I'd rather stick to textfiles for stuff like this.) I haven't felt the compulsion to go beyond searching in less or vim, though.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/463533.html#comments

Tags:

booyeah, I'm good!

So some months ago I worked on an AVL tree in pure C. My main goal was to get self-balancing happening at all, to demystify that process, and I did that; getting the code to be robust or even asymptotically appropriate (I'm still calculating heights every time I need to, not caching and updating them) was far down the priority list. So, while I tried to be correct in handling memory, it would not have surprised me if subtle bugs still existed.

My past work experience didn't emphasize use of static analysis tools. I think I played with lint a bit on my own, but relying on it or valgrind wasn't a thing. I finally investigated them today, ending up with cppcheck for source code check, and valgrind for what it does. And ran them on my directory of C/C++ exericses, which as small exercises, could easily have had lots of problems.

...not so much! cppcheck found a few problems, most notably a missing return value I wasn't testing properly in linked list, and a realloc bug[1] in my memoized Fibonacci table, and an unset ID variable in a threading program, but nothing else, including in the AVL tree or the new C++ hash table.

valgrind found some memory leaks in linked list and AVL tree... only because the testing main() for each was creating structures and then not freeing them before exit, because who cares at that point? With a manual destroy added, both check out clean. Which the list really should, it's pretty simple, but I'm stoked about the AVL tree doing so, since it's complex and memory correctness wasn't a top priority. Seems like I do have good habits.

There's also clang's static analyzer, supposedly deeper than cppcheck, though much slower to use. It's happy with my codes too.

Of course, valgrind can only test what's executed, so more use might uncover more bugs, but still, I feel good.


[1] ptr = realloc (ptr, ...) sets ptr to NULL if the realloc fails, which means a memory leak if nothing else is pointing to what ptr had been pointing to. Not having used realloc much, plus also not worrying about errors in a tiny program, this didn't stand out to me.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/463258.html#comments

inet_pton 0.0.0.0 surprise

So, I've been working today on cloning my Ocaml chat program in C++. It's going slowly as I work on infrastructure, like exception-throwing wrappers to libc socket functions, and a RAII class for file descriptors.

In the process, I found something. I'd been using inet_pton() on the user provided server name, forgetting that I have to look it up first. I was getting away with it because testing has been local, client connect to localhost. My first code wasn't error checking inet_pton, but I got around to making the Inet_pton wrapper, which started throwing exceptions. inet_pton is supposed to return 1 on success (with the IP address written into a parameter), and 0 on invalid input. Turns out, given the string "localhost", it returns 0 but *also* writes in the local IP address.

That, or some weirder default was happening... yeah, on going the other way, I find the address (written or more likely just left over from the usual memset/bzero initialization) is 0.0.0.0... which connects to localhost, just like the well-known 127.0.0.1. Huh. Guess I should look up 0.0.0.0... which looks messy an multi-purpose, but yeah, this seems one potential behavior of it, especially on a DHCP machine. OTOH, neither of the remote servers I have access to will connect to themselves via that address, so it's not reliable.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/463093.html#comments

Kate Elliott on writing women

9k word essay on writing women into fantasy "without quotas"; mostly it's a catalogue of the diverse role of women through history.

http://www.tor.com/2016/03/23/writing-women-characters-into-epic-fantasy-without-quotas/

Some random notes I took:

1300s Lollards insisted on equality of men and women

Napoleon’s civil code restricted married women’s property rights, for
example

In tenth century Saxony there is “plenty of evidence that women
accumulated, transmitted and alienated predial estate"hi

In medieval Valldigna, Spain, Aixa Glavieta “went to court six times
until she forced the Negral family return to her the terrace with two
mulberry trees”

Zhou Daguan on Cambodia: "The local people who know how to trade are all
women. So when a Chinese goes to this country, the first thing he must
do is take in a woman, partly with a view to profiting from her trading
abilities"

Anglo-Saxon Chronicles has king's sisters witnessing founding of a
monastery.

A woman of high birth in any stratified society will have companions and
servants commensurate with her position. ..She will also usually retain
important ties to her birth family, and will be expected to look after
their interests.

In many cases the one person a lord, prince, king, or emperor could
absolutely trust was his mother: only she, besides himself, had full
investment in his success.

[Alexander] appointed [Ada] to the governership of Caria as a whole.
This woman was the wife of Hidrieus—and also his sister, a relationship
in accordance with Carian custom; Hidrieus on his death-bed had
bequeathed her his power, government by women having been a familiar
thing in Asia from the time of Semiramis onward.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/462819.html#comments

party food planning math

One last (probably) post inspired by Saturday.

A naive planner, trying to be considerate, might think "I'll have 40% vegan guests, 40% veg'n guests, and 20% omnivores, so I should have 40% vegan food... and 20% meat."

This is wrong! The vegans can only eat the vegan food, which will probably be poached by the other two groups. Put another way, if you locked the groups into only getting food from their own tables, then the omnivore table would likely *not* be 100% meat; even barbecues tend to have non-meat sides. 20% * (less than) 100% = less than 20%.

How *should* you distribute the food? I don't think there's a better answer than handwaving. But here's an illustrative model:

Imagine a vegan, two veg'ns who eat half-vegan and half-not food, and one omnivore who'll eat half meat, 1/4 vegan, and 1/4 veg'n. This implies that 9/16 of the food, should be vegan, 5/16 vegetarian, and 2/16 meat. One vegan, but more than half the food suitable for them -- again, because good vegan food will not be exclusive to them.

But of course it depends on your groups. If you know your veg'ns won't touch anything that's not dairy, and that your omnivores will only eat meat, then the naive approach is more valid. It can also apply to some main courses; if you're doing burgers in the first example, then 40% vegan, 40% veg'n-with-egg burgers, and 20% beef burgers, might make sense. Though there's still a chance of an omnivore trying the black bean or whatever burger out of curiosity, so poaching can still happen.

In my case, I traditionally have hummus and dates, and everyone eats those. I was hoping for 1/3 vegans at this party, and expecting 2/3 vegan or veg'n, and laid out entirely vegan food but for some camembert and some chicken. In retrospect I 'should' perhaps have gotten more cheese, to serve four people, though given actual attendance it worked out just fine.

I suppose that if you're planning a BBQ plus one vegan guest invited for socializing, it can make sense to just mark off some food as their territory while everyone else focuses on the pile of meats. Everything's situational; my main point is to caution against naive math.

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/462346.html#comments

Tags:

more on party costs

(I'm not trying to 'win' Iron Blogger, I'm just having lots of thoughts.)

I'm still bugged by the expenditures. You can live on like $5-6/day, surely I shouldn't be spending more than that per person for one meal? I spent $40 hoping for six people, that's nearly $7/person. In hindsight, given 4 people and what was consumed, I could have skipped the cashews, chips and salsa, less popular sausage, and one bag of pita, bringing cost down to $24, or $6/person, and we've probably have scoured everything clean except the chicken, due to lack of enough carnivores.

But, I guess it depends on what you get: eating frugally means stuff like pasta and rice and beans, or bread and peanut butter. Cheese, (good) crackers, and tomatoes are comparatively expensive: e.g. the crackers were about $5/lb. They're nutrient dense, being dry and fatty, but still twice the $/calorie of even overpriced whole wheat pasta. The tomatoes were $6, or $4/lb, which might be expensive even for tomatoes -- it's been a while since I bought any other kinds -- though as we ate nearly all, I have no regrets.

So basically, yes you can feed people cheaply if you prepare normal staple-based meals, but if you go for savory finger food, it'll be more expensive. Which is fine, it's just good to know and set my expectations accordingly. We probably still came in under restaurant cost, and finger food has advantages in prep (good for me as host) and not tying people to a table and large plate (good for guest circulation and freedom, though that's more relevant for larger parties.)

(Conversely it may be easier to overeat with finger food, if you just keep eating until it's gone or you feel dangerously stuffed.)

(I have a dim possible memory of realizing my old parties were more expensive than I expected, too.)

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/462147.html#comments

Tags:

holy crap auto is awesome

One thing easy to miss about Python is how it can easily print anything, including lists of dictionaries of lists of objects.  C++, not so much.  So I wrote a simple template function to print a vector of printable types, and then one for deques.

template<class T>
void pr_vector(const vector <T> &v) {
    for (auto i : v)
        cout << i;
    cout << "\n";
}
template<class T>
void pr_deque(const deque <T> &v) {
    for (auto i : v)
        cout << i;
    cout << "\n";
}

Well, lots of duplication there.  I tried templating on the container type too, template <class C, class T>, but the resulting C <T> didn't work; it probably should with some syntax, but I don't know what, yet.

But I figured I'd try auto:

void pr_cont(const auto &v) {
    for (auto i : v)
        cout << i;
    cout << "\n";
}

...that subsumes both templates.  And lots of others.  vector, deque, list...  Of course, the values themselves have to be printable, it can't handle a vector<pair<int, string>> because there's no printing on pairs.  But still, for C, this is amazing!

See the comment count unavailable DW comments at http://mindstalk.dreamwidth.org/462054.html#comments

Profile

Phoenix
mindstalk
Damien Sullivan
Website

Latest Month

February 2017
S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728    

Tags

Syndicate

RSS Atom
Powered by LiveJournal.com
Designed by Lilia Ahner