The "IT DOESN'T WORK!" thread

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

Princess Marzipan
Posts: 7717
Joined: Sun May 27, 2007 5:28 am UTC
Location: neither a road, nor an island

Re: The "IT DOESN'T WORK!" thread

Postby Princess Marzipan » Sun Jul 07, 2013 9:50 pm UTC

jestingrabbit wrote:When you say objects are identical in python, I would normally take that to mean the id(obj1) == id(obj2). Is this the case?

You might need to post the code for "liststuff" at some point.
If I change obj1's list, obj2 and obj3's lists are changed as well.

The superclass is 'Fief'. The subclasses are System and Planet.
The liststuff adds 'vassals' to a Fief.

Code: Select all

    def add_vassals(self, new_vassals):
        for new_vassal in new_vassals:
            if new_vassal.lord != None:
                new_vassal.lord.vassals.remove(new_vassal)
                new_vassal.lord.recalculate()
            new_vassal.lord = self           
        self.vassals.extend(new_vassals)
        self.recalculate()


I think the issue is that I'm not properly implementing the inheritance of the __init__ method, since I don't quite grok that.
__init__ declarations for Fief, System, and Planet respectively. Including System and Planet calls to Fief's __init__, which is the first line of their __init__s.

Code: Select all

#Fief
def __init__(self, name, fieftype, lord = None, vassals = []): # Fief
#System
def __init__(self, name, size, terrain, moon = None, anomaly = None, resource = None, system = None):
        super(Planet, self).__init__(name, 'planet', lord = system)
#Planet
def __init__(self, name, empire = None, planets = []):   
        super(System, self).__init__(name, 'system', lord = empire, vassals = planets)


After this runs, both Risa and Sol contain RisaI-VI and SolI in their vassals list.

Code: Select all

Risa = System('Risa')
RisaI = Planet('RisaI', 'tiny', 'ocean')
RisaII = Planet('RisaII', 'small', 'tundra')
RisaIII = Planet('RisaIII', 'medium', 'desert')
RisaIV = Planet('RisaIV', 'medium', 'barren')
RisaV = Planet('RisaV', 'large', 'methane')
RisaVI = Planet('RisaVI', 'huge', 'asteroids')
risa_planets = [RisaI, RisaII, RisaIII, RisaIV, RisaV, RisaVI]
Risa.add_vassals(risa_planets)

Sol = System('Sol')
SolI = Planet('SolI', 'tiny', 'terran')
Sol.add_vassals([SolI])
"It's Saturday night. I've got no date, a two-liter of Shasta, and my all-Rush mixtape. Let's rock!"
"I am just about to be brilliant!"
General_Norris, on feminism, wrote:If you lose your six Pokémon, you lost.

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Sun Jul 07, 2013 11:07 pm UTC

Default arguments in Python are, unfortunately, evaluated once, and then the value reused. Usually this isn't a problem, except if you do:

Code: Select all

def foo(x=[]):
  ...
then every time you call foo with the default parameter, x will be the same list object, rather than making a new empty list each time. Just try this:

Code: Select all

def foo(x=[]):
  x.append(5)
  print(x)
foo()
foo()
foo()

The usual idiom is:

Code: Select all

def foo(x=None):
  if x is None:
    x = []
  ...
to avoid this problem.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

Princess Marzipan
Posts: 7717
Joined: Sun May 27, 2007 5:28 am UTC
Location: neither a road, nor an island

Re: The "IT DOESN'T WORK!" thread

Postby Princess Marzipan » Sun Jul 07, 2013 11:24 pm UTC

Wow, it would have been quite some time before I stumbled upon that on my own.

In your honor:

Code: Select all

sacrifice = Goat()
del sacrifice


Thanks!!!
"It's Saturday night. I've got no date, a two-liter of Shasta, and my all-Rush mixtape. Let's rock!"
"I am just about to be brilliant!"
General_Norris, on feminism, wrote:If you lose your six Pokémon, you lost.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: The "IT DOESN'T WORK!" thread

Postby TheChewanater » Mon Jul 08, 2013 1:35 am UTC

If you're doing this more than once, I think decorators are a more Pythonic solution.

Code: Select all

def default_empty_list(f):
    return lambda l = None: f([]) if l is None else f(l)

@
default_empty_list
def foo
(l):
    l.append(10)
    print l

foo
() #prints [10]
foo() #prints [10]
foo([42]) #prints [42, 10]
foo([666]) #prints [666,10]       


Or, a more generalized version, probably overkill:

Code: Select all

class default:
    def __init__(self, ctor):
        self.ctor = ctor
    def __call__
(self, f):
        return lambda l = None: f(self.ctor()) if l is None else f(l)

@default(list)
def foo(l):
    l.append(10)
    print l

@default(dict)
def bar(d):
    d['foo'] = 50
    print d
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

EvanED
Posts: 4324
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby EvanED » Mon Jul 08, 2013 2:45 am UTC

TheChewanater wrote:If you're doing this more than once, I think decorators are a more Pythonic solution.
Wat? No. Just because Python has decorators doesn't mean that using them is always the most Pythonic answer.

Default arguments are fairly common; a decorator like you suggested is neither a common idiom nor present in the language itself, whose documentation recommends the same thing as phlip.

Even the more general of your proposed decorators is, IMO, hopelessly specific in its use case, which is a single-argument function for which the default value you want has a no-argue function already created that constructs it. (I guess you could pass a lambda.) It may be possible to create a default-arg decorator that is actually general, but yours is not it.

The main benefit I see of using your decorator is that it makes your function definition ever-so-slightly shorter. But that comes at a cost of foregoing an idiom that any Python programmer will recognize instantly for something which is entirely unfamiliar. The only time I think that's an appropriate tradeoff is if you're doing something like that not just "more than once", but incredibly often, like you've got a dozen or two functions that you use that decorator on.

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Tue Aug 06, 2013 8:27 am UTC

Blarg, friggin popup blockers... I'm very glad you exist, and all, but why do you have to be so friggin' inscrutable and inconsistent?

On this page I'm working on, I'm trying to popup a window on pageload. Specifically, I have a hidden form, method=post target=_blank, which I call .submit on from an onload event. This triggers the popup blocker, as well it should. I'm trying to detect when this happens, so that I can show a message with instructions on (a) how to disable the popup blocker for this site, and (b) a button the user can click to trigger the popup (which will work this time, since it's triggered by a user click).

Except I can't for the life of me figure out how to detect that. Most search results when you search for this sort of thing assume you're using window.open(), but we're not... and form.submit() doesn't have a way to get the new window. Even if it did, it's cross-site, so I couldn't interact with it even if I wanted to.

The annoying part is that, for me, form.submit() throws an exception... sometimes. Sitting here, in Firefox, in the same browser instance, in two different tabs, I have the same page running on two different servers, which what is, as far as I can tell, the same JS code. On one, on loading the page, the form submit triggers the "popup blocked" message, and then fails silently. On the other, the form submit triggers the "popup blocked" message and then throws a NS_ERROR_FAILURE exception, which I could theoretically catch and make use of. But I can't figure out why it isn't happening consistently. I'd expect the behaviour to be different in different browsers, or different versions... but this is the same browser, running side-by-side, and it's still behaving differently. And I can't for the life of me figure out why. Google is no help, it just finds the millions of people trying to cheat their way past the popup blocker, and get their popup to work despite it, and no matter what search terms I try I can't find anything relevant about this exception, what triggers it and what doesn't.

I'm probably going to end up rebuilding the whole thing so that the window is popped up earlier in the process, when the user's actually clicking the button, to avoid the whole thing... but that whole exception thing really confuses me.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Carlington
Posts: 1583
Joined: Sun Mar 22, 2009 8:46 am UTC
Location: Sydney, Australia.

Re: The "IT DOESN'T WORK!" thread

Postby Carlington » Tue Aug 06, 2013 9:15 am UTC

While this isn't exactly a solution to the problem as stated, and may not be applicable, is it at all possible to just have a link on the page (or redirect to a page with this link on it), something to the effect of "If the pop-up window fails to open, click here"?
Kewangji: Posdy zwei tosdy osdy oady. Bork bork bork, hoppity syphilis bork.

Eebster the Great: What specifically is moving faster than light in these examples?
doogly: Hands waving furiously.

Please use he/him/his pronouns when referring to me.

jazz14456
Posts: 58
Joined: Thu Jul 04, 2013 9:04 pm UTC
Location: New Netherlands

Re:

Postby jazz14456 » Wed Aug 07, 2013 9:07 pm UTC

evildave wrote:I hate tracking a 'software bug' down to a hardware problem.

It's like a whole day of my life has been ripped away.

Sometimes more than one day.


I have really come to hate... well, everybody.

I've got to learn NOT TO give computers and old equipment to people I know. They always want lifetime service with FREE PARTS to be thrown in with the deal.

"The computer's broken!"
"What's wrong with it?"
"You have to come see!"
(Drop everything, come to see...)
"See, I can log into every site on the internet, but I can't log into THIS one!"
(Under my breath, bad words begin to form.)
"And when you can't get channel 7, is your TV broken?"
"They're always fuzzy, and what's that have to do with anything?"
"Never mind. Have you contacted {people who run web site}?"
"No. I wanted to ask you."
"Well, it's THEIR stuff that's down."
"Oh, wait, I got an email about 'down for planned maintenance'..."
"Super."

Sounds like you would benefit greatly from reading Boundaries by Henry Cloud and John Townsend. Its an easy read and you could be a lot happier with it.
This place is ending and its time to go.

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Wed Aug 14, 2013 10:03 am UTC

OK, given that OleVariant is a compiler-library-provided variant class intended for use with the compiler-library-provided COM interface layer, and DecodeVariant is my own function for turning these into human-readable strings, and AnsiString and WideString are the VCL managed string classes...

What do you think the following should do?

Code: Select all

OleVariant strLiteral("Hello");
std::cout << DecodeVariant(strLiteral) << std::endl;

OleVariant wstrLiteral(L"Hello");
std::cout << DecodeVariant(wstrLiteral) << std::endl;

OleVariant strObject(AnsiString("Hello"));
std::cout << DecodeVariant(strObject) << std::endl;

OleVariant wstrObject(WideString(L"Hello"));
std::cout << DecodeVariant(wstrObject) << std::endl;

Spoiler:
If your guess was:

Code: Select all

Boolean: True
Wide String: Hello[followed by 14257 spaces]
Wide String: Hello
Wide String: Hello
and then crash in the destructor for wstrLiteral, then congratulations, you win, I guess.

Now, I eventually found out that the fact that the non-wide string is being stored as a wide string is actually supposed to be a feature... COM only handles Unicode strings, not 8-bit-char strings, so this is supposed to help you interface with that... given nearly everything else in this stupid library works with AnsiString exclusively. And I think the constructor that takes wchar_t* is expecting it to be created by SysAllocString, and it's trying to free it... or something. Whatever it's doing, it's managing to corrupt memory and free something it didn't create. At least, that's my guess... none of this is documented worth a damn. And there just straight-up isn't a char* constructor, so it's automatically converting the char* to bool and using the bool constructor. Because why not.

I just spent a couple of hours trying to track down a bug that ended up coming from:

Code: Select all

xmlNode->SetAttribute(L"SomeName", "SomeValue");
because the second parameter to SetAttribute is for some reason an OleVariant... so it was coming out as

Code: Select all

<SomeNode SomeName="True" />
I changed it to

Code: Select all

xmlNode->SetAttribute(L"SomeName", L"SomeValue");
and started getting random crashes. Eventually changed it to

Code: Select all

xmlNode->SetAttribute(L"SomeName", WideString(L"SomeValue"));
and now it works. Stupid incomplete library functions...

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Yakk
Poster with most posts but no title.
Posts: 11045
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Thu Aug 15, 2013 1:26 pm UTC

One of the many reasons why `operator char*` and similar are bad ideas.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

mr-mitch
Posts: 477
Joined: Sun Jul 05, 2009 6:56 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby mr-mitch » Fri Sep 06, 2013 2:53 pm UTC

I was wondering how you might get a unix based system (debian) display one of the pts on the main screen?

To add a bit of context, I have a raspberry pi without a keyboard with wifi and it's connected via hdmi to my TV. I have a wireless keyboard that is able to connect to a computer in another room. I can ssh using the keyboard into the raspberry pi using the wireless keyboard and the other computer. The problem is, the tty which is displayed by default obviously isn't the pts that the ssh session uses. Putting a keyboard on the pi is out of the question because of power/usb availability issues.

Is it possible to display the pts on the TV?

(whoops realised I put it in the wrong thread)

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Sat Sep 07, 2013 5:19 pm UTC

Have a look at the man page for "openvt"... that'll let you create a new virtual terminal, and run some command in it. There's also "chvt", which lets you switch between terminals.

Now, you can't directly use the same tty for both a virtual terminal and an ssh connection... however, you can use screen's multiuser mode to multiplex a terminal across both screens.

Putting it all together: after sshing into the machine, run:

Code: Select all

screen -S sharedterm
That'll start up a named screen session, and start up your shell inside. Once you're in there, hit Ctrl+A then : to get up the console, and enter "multiuser on". Then run

Code: Select all

openvt -s -- screen -x -r sharedterm
That'll make a new virtual terminal, switch to it, and run screen attached to the same session. Everything you do then should be mirrored between your ssh connection and the console. When you want to disconnect from the SSH session, you can just hit Ctrl+A, Ctrl+D to detach, and the shell will keep running, but the ssh session will be disconnected from it. You can reconnect to it by running "screen -x -r sharedterm". Hit Ctrl+A, ? for more options, and read through screen's man page.

You may need to run all of this as root, and for best results you probably want to make sure the window you're running your SSH connection through is 80x25 (screen multiuser mode can get weird if the attached terminals are different sizes).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

mr-mitch
Posts: 477
Joined: Sun Jul 05, 2009 6:56 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby mr-mitch » Sun Sep 08, 2013 10:38 am UTC

Awesome, thanks. openvt and chvt are just what I need. I've tried to search but I was obviously using the wrong words.

I had to run everything as root (including creation of the screen); otherwise I'd get "there is no matching screen" error. Are screens user-specific? I never knew that.
Although 80x25 in a 1920x1080 TV is a bit unnerving.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1397
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby Xenomortis » Thu Nov 14, 2013 3:32 pm UTC

Code: Select all

aspPanelOne.Visible = some expression that evaluates to true
aspPanelTwo.Visible = Not aspPanelOne.Visible
Response.Write(aspPanelOne.Visible.ToString + aspPanelTwo.Visible.ToString)

Prints "FalseFalse" and the contents of both panels are visible. The panels are not visible by default.
:D

Edit:
Oh wait, it was in the wrong event handler.
Image

User avatar
Carlington
Posts: 1583
Joined: Sun Mar 22, 2009 8:46 am UTC
Location: Sydney, Australia.

Re: The "IT DOESN'T WORK!" thread

Postby Carlington » Tue Nov 26, 2013 7:51 am UTC

Having issues with an RNG in Lua, can't remember if I've asked about RNGs here before.
Basically, Lua treats functions as a data type, and assigns them to a variable to work with them. I'm trying to write a basic function that uses math.random(lower,upper), but Lua evaluates before assigning, so the random number will be selected exactly once, when the variable is first called, and then the function will always return that value, instead of generating a new random number each time. I can recognise exactly what's wrong, and how it's breaking, but I cannot figure out how to fix it.
Kewangji: Posdy zwei tosdy osdy oady. Bork bork bork, hoppity syphilis bork.

Eebster the Great: What specifically is moving faster than light in these examples?
doogly: Hands waving furiously.

Please use he/him/his pronouns when referring to me.

User avatar
Jplus
Posts: 1692
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Jplus » Tue Nov 26, 2013 12:20 pm UTC

Code: Select all

myRNG = function ( ) math.random(lower, upper) end
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
Carlington
Posts: 1583
Joined: Sun Mar 22, 2009 8:46 am UTC
Location: Sydney, Australia.

Re: The "IT DOESN'T WORK!" thread

Postby Carlington » Wed Nov 27, 2013 2:54 am UTC

Here be Lua:
Spoiler:

Code: Select all

function ai_move()
   math.random(1,3)
end


function move_textifier(move)
   if move == 1 then
      return "Computer threw scissors!"
   elseif move == 2 then
      return "Computer threw paper!"
   elseif move == 3 then
      return "Computer threw rock!"
   end
end

print(move_textifier(ai_move()))


No matter what, every time I run that program, it gives me "Computer threw rock!" as output.
Kewangji: Posdy zwei tosdy osdy oady. Bork bork bork, hoppity syphilis bork.

Eebster the Great: What specifically is moving faster than light in these examples?
doogly: Hands waving furiously.

Please use he/him/his pronouns when referring to me.

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Wed Nov 27, 2013 3:09 am UTC

Does the RNG need to be seeded? I know some languages, if you call the rand()-equivalent without calling the srand()-equivalent first, it'll default to a seed of 0 or something equally useless, so you'll always get the same sequence of numbers out...

[edit]
After Googling... try sticking a

Code: Select all

math.randomseed(os.time())
at the top of the program.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Carlington
Posts: 1583
Joined: Sun Mar 22, 2009 8:46 am UTC
Location: Sydney, Australia.

Re: The "IT DOESN'T WORK!" thread

Postby Carlington » Wed Nov 27, 2013 3:32 am UTC

That worked. Hum. Danke, phlip.
Kewangji: Posdy zwei tosdy osdy oady. Bork bork bork, hoppity syphilis bork.

Eebster the Great: What specifically is moving faster than light in these examples?
doogly: Hands waving furiously.

Please use he/him/his pronouns when referring to me.

quark-gluon-plasma
Posts: 4
Joined: Sat Nov 30, 2013 11:37 pm UTC

Re:

Postby quark-gluon-plasma » Sun Dec 01, 2013 4:13 am UTC

Daem0hn wrote:After spending a day tracing through the program in GDB i found that upon doing an x*6 calc, for some strange reason, it would always reset the 2nd bottom stack item to 0 when the 6 was popped from the stack (dont ask me why, to this day i have not got a clue).

Eventually i gave up on the problem and was looking through my code for any final revisions i could make. I noticed that id malloced some memory and not freed it, so i freed it up at the end of the program. Compiled, Ran one last test, decided to test the x*6 problem, and it worked :shock:

The memory i freed had _nothing_ to do with the stack, nor to do with the numeric processing. It was to hold some random snippet of user information so i have no idea why freeing it up fixed me problem.


So in conclusion: C, crazy stuff.


You ran into a hardware, OS or compiler bug! well done.

User avatar
Diadem
Posts: 5649
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Wed Dec 11, 2013 11:15 am UTC

So I was playing around with the new <random> library in c++11 (Well visual studio 2010, which has some but not all of the c++11 functionality), and I have this weird problem:

This compiles:

Code: Select all

#include <iostream>
#include <random>

int main() {
    unsigned int x = 5;
    std::default_random_engine engine;
    engine.seed(5);
}


This doesn't compile:

Code: Select all

#include <iostream>
#include <random>

int main() {
    unsigned int x = 5;
    std::default_random_engine engine;
    engine.seed(x);
}

It gives the error: "error C2064: term does not evaluate to a function taking 0 arguments".

I've never seen that before. Why would it work with a numeric literal but not an integer variable? The error is not at all useful either. Google tells me most people encounter that error when they mix up variables and functions, but I don't see how that applies here. According to this, seed() expects an argument of type 'result_type', unfortunately I can't find how this type is defined anywhere, but it definitely should be an integer type. And it doesn't seem to matter if I pass an int or an unsigned int or anything else I've tried.

I'm at a loss.

Edit: some more data:

I tried some different enginges:
- With std::mt19937 it also fails.
- With std::minstd_rand0 it works, though I get the same error again if I take 'const int x = 5', which makes even less sense than before.

I'm starting to think this might be a compiler bug.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Xenomortis
Not actually a special flower.
Posts: 1397
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: The "IT DOESN'T WORK!" thread

Postby Xenomortis » Wed Dec 11, 2013 11:26 am UTC

Compiles for me with VS2012.
No warnings.
Image

User avatar
Diadem
Posts: 5649
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Wed Dec 11, 2013 3:43 pm UTC

Huh. So a bug in VS2010 then? It's possible. C++11 support in VS2010 is shaky at best.

Not being able to dynamically seed random variable generators makes them a bit worthless though.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

EvanED
Posts: 4324
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby EvanED » Wed Dec 11, 2013 4:41 pm UTC

Possibly. Wouldn't be the first... I've discovered at least one bug in the MSVC libraries.

However, it works (for me, anyway) if I define x to be an unsigned long rather than unsigned int. The reason appears to be as follows. MSVC 2010's default_random_engine provides three seed functions:

Code: Select all

void seed(unsigned long _X0 = default_seed,
          _Ty _Fx = (_Ty)1812433253)
{...}

#if _HAS_CPP0X
void seed(seed_seq& _Seq)
{...}
#endif /* _HAS_CPP0X */

template<class _Gen>
void seed(_Gen& _Gx, bool = false)
{... _Gx() ... }

The seed_seq version isn't relevant, but the other two are. What seems to be happening is that the compiler determines that seed<int>(int, ...) is a better match than seed(unsigned long, ...), which it is, and calls that version.

I think this is actually "correct" reasoning. (I don't think SFINAE kicks in for errors when instantiating the body of a function template, so SFINAE shouldn't cause template<T> seed(T&...) to be excluded from the candidate set.) I'd be interested to know what MSVC 2012 does that's different.

Fixed SFINAE speeling erorr for JPlus :-)
Last edited by EvanED on Wed Dec 11, 2013 5:17 pm UTC, edited 1 time in total.

User avatar
Jplus
Posts: 1692
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Jplus » Wed Dec 11, 2013 5:13 pm UTC

SFINAE
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11045
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: The "IT DOESN'T WORK!" thread

Postby Yakk » Wed Dec 11, 2013 6:31 pm UTC

Bless you.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Diadem
Posts: 5649
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Wed Dec 11, 2013 11:22 pm UTC

EvanED wrote:Possibly. Wouldn't be the first... I've discovered at least one bug in the MSVC libraries.

However, it works (for me, anyway) if I define x to be an unsigned long rather than unsigned int. The reason appears to be as follows. MSVC 2010's default_random_engine provides three seed functions:

Code: Select all

void seed(unsigned long _X0 = default_seed,
          _Ty _Fx = (_Ty)1812433253)
{...}

#if _HAS_CPP0X
void seed(seed_seq& _Seq)
{...}
#endif /* _HAS_CPP0X */

template<class _Gen>
void seed(_Gen& _Gx, bool = false)
{... _Gx() ... }

The seed_seq version isn't relevant, but the other two are. What seems to be happening is that the compiler determines that seed<int>(int, ...) is a better match than seed(unsigned long, ...), which it is, and calls that version.

I think this is actually "correct" reasoning. (I don't think SFINAE kicks in for errors when instantiating the body of a function template, so SFINAE shouldn't cause template<T> seed(T&...) to be excluded from the candidate set.) I'd be interested to know what MSVC 2012 does that's different.

Fixed SFINAE speeling erorr for JPlus :-)


That explanation kind of makes sense, but I still have a few question:

1) I can't find that third constructor anywhere in the documentation. I can see it in the source file, it's indeed there, but it's not in the documentation. I suppose it's there for internal use or something, but in that case it interfering with the normal constructors should, I think, be considered a bug.

2) How can it instantiate a templated function when I'm not passing a template type? What does it use for the type?

3) Why are numerical literals allowed? Shouldn't they also trigger the third overload?
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

EvanED
Posts: 4324
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby EvanED » Thu Dec 12, 2013 12:01 am UTC

Diadem wrote:1) I can't find that third constructor anywhere in the documentation. I can see it in the source file, it's indeed there, but it's not in the documentation. I suppose it's there for internal use or something, but in that case it interfering with the normal constructors should, I think, be considered a bug.
The weird thing is that the standard apparently specifies a different templated version of template<T> seed(T x), which calls x.generate() -- which would cause essentially the same error, but with .generate instead of operator(). That version corresponds to the second overload in the MSVC 2010 code, which is not templated.

I looked at the overloads that are present in the MSVC 2012 version:

Code: Select all

void seed(unsigned long _X0 = default_seed)
{...}

template<class _Seed_seq>
typename enable_if<
    !is_convertible<_Seed_seq, _Ty>::value,
                    void>::type
seed(_Seed_seq& _Seq)
{...}

Note the enable_if that disables the templated overload when it would "ambiguate" the non-template.

That matches the standard. I'm too lazy to verify this right now, but there's a pretty good chance that what happened is the <random> header underwent multiple revisions during the development of C++11, and the version with 2010 corresponds to an older version.

2) How can it instantiate a templated function when I'm not passing a template type? What does it use for the type?

Hmmm? You very rarely need to specify template parameters to a function template; usually, function templates (including seed) are written so that the compiler is able to deduce the template parameters from the actual function parameters.

3) Why are numerical literals allowed? Shouldn't they also trigger the third overload?
That is a damn good question. :-)

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby phlip » Thu Dec 12, 2013 12:16 am UTC

EvanED wrote:
3) Why are numerical literals allowed? Shouldn't they also trigger the third overload?
That is a damn good question. :-)

Because the method takes a reference, so it doesn't get applied when you have a parameter that isn't an lvalue...

For instance:

Code: Select all

#include <iostream>
#include <typeinfo>

struct Foo
{
   void call(unsigned long x) { std::cout << "Foo::call(unsigned long)" << std::endl; }
   template<class T> void call(T& x) { std::cout << "Foo::call<" << typeid(T).name() << ">(T&)" << std::endl; }
};

struct Bar
{
   void call(unsigned long x) { std::cout << "Bar::call(unsigned long)" << std::endl; }
   template<class T> void call(T x) { std::cout << "Bar::call<" << typeid(T).name() << ">(T)" << std::endl; }
};

int main()
{
   unsigned int x = 5;
   Foo f;
   Bar b;
   f.call(5); // Foo::call(unsigned long)
   f.call(x); // Foo::call<unsigned int>(T&)
   b.call(5); // Bar::call<int>(T)
   b.call(x); // Bar::call<unsigned int>(T)
   std::cin.ignore();
}
GCC gives the same result (aside from its type_info::name is less readable), so if this is wrong, it's at least a bug in both MSVC and GCC. Unfortunately I don't know the C++ standard well enough to say for certain.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

EvanED
Posts: 4324
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby EvanED » Thu Dec 12, 2013 2:28 am UTC

phlip wrote:Because the method takes a reference, so it doesn't get applied when you have a parameter that isn't an lvalue...
Good catch; I missed that.

GCC gives the same result (aside from its type_info::name is less readable), so if this is wrong, it's at least a bug in both MSVC and GCC. Unfortunately I don't know the C++ standard well enough to say for certain.
The behavior of both compilers is correct by the standard given the code input; what I don't know for sure is how the MSVC implementation of the seed seed functions matched whatever was the latest C++11 proposals at the time.

User avatar
Diadem
Posts: 5649
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Thu Dec 12, 2013 9:39 am UTC

That all makes a lot of sense. Thanks everybody! I think I understand it now.

You never seem to stop learning new surprising things about c++.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
robby hobby
Posts: 5
Joined: Tue Nov 03, 2009 1:59 am UTC
Location: portland, or

Re: The "IT DOESN'T WORK!" thread

Postby robby hobby » Wed Dec 18, 2013 8:26 am UTC

Hi
I'm implementing this formula for approximating the position of the sun, this one spits out azimuth and altitude. inputs are time (day, hour, min, second), latitude longitude. I'm referencing this paper here: http://www.esrl.noaa.gov/gmd/grad/solcalc/solareqns.PDF

I've almost got it, and it's really stunning! The analemmas near the equator get fancy crazy.

I am convinced the problem is of the trig kind. All the azimuth values are bounded inside 180˚, not 360˚. I have my eyes on you, acos and asin. but really i have no clue.. here, here's a screenshot: https://raw.github.com/robbykraft/EquationOfTime/master/SolarPosition/screenshot.png

Here's my implementation of the paper:

Code: Select all

void solarPositionAtLatitude(float longitude, float latitude, int day, int hour, int minute, int second){
    int timezone = -(floor(longitude/360.*24)+1);  //timezone from UTC (California = +8)
    float y = 2*PI/365 * (day-1 + (hour-12)/24.);
    float eqtime = 229.18 * (0.000075 + 0.001868*cos(y) - 0.032077*sin(y) - 0.014615*cos(2*y) - 0.040849 * sin(2*y) );
    float decl = 0.006918 - 0.399912*cos(y) + 0.070257 * sin(y) - 0.006758 * cos(2*y) + 0.000907 * sin(2*y) - 0.002697 * cos(3*y) + 0.00148 * sin(3*y);
    float time_offset = eqtime - 4 * longitude + 60 * timezone;
    float tst = hour * 60 + minute + second / 60. + time_offset;  // in minutes
    float ha = tst/4. - 180;
    float zenithRight = (sin(latitude*PI/180.) * sin(decl) + cos(latitude*PI/180.) * cos(decl) * cos(ha*PI/180.));
    zenith = acos( zenithRight );
    float top = sin(latitude*PI/180.) * cos(zenith) - sin(decl);
    float bottom = cos(latitude*PI/180.) * sin(zenith);
    float azimuthRight = (top / bottom);
    azimuth = 180+acos(-azimuthRight)/PI*360.;
//    azimuth = 180-acos(-azimuthRight)/PI*360.;
}


see that last commented out line? if i switch them, it flips them to the other side. not a permanent solution at all. just some perspective.

maybe I am getting the right results and I just don't understand astronomy well enough.

(i am taking liberties rounding 365 days to 360 sometimes)

if you're a visual person, here's some places I put the code (i wrote it in processing)
https://github.com/robbykraft/EquationOfTime
run in-browser: http://robbykraft.com/solarequations.html

thanks so much everybody!
Robby

User avatar
thoughtfully
Posts: 2243
Joined: Thu Nov 01, 2007 12:25 am UTC
Location: Minneapolis, MN
Contact:

Re: The "IT DOESN'T WORK!" thread

Postby thoughtfully » Wed Dec 18, 2013 2:35 pm UTC

I haven't looked at your code, but USNO has software, already implemented, that you can download. It's got FORTAN and C versions, and I made Python bindings I can pass along if you're interested in that.
Image
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
-- Antoine de Saint-Exupery

User avatar
PM 2Ring
Posts: 3619
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Re: The "IT DOESN'T WORK!" thread

Postby PM 2Ring » Sat Dec 21, 2013 2:24 am UTC

The trick is to rearrange your formulas to avoid asin() & acos() and use atan2() instead.

Here's an excerpt from some C code I wrote late last century when I was studying sundial stuff. My program mostly uses USNO algorithms & data, but (IIRC) I got the (RA, declination) -> (altitude, azimuth) formulae from a book on spherical trig.

Sorry about the crappy variable names. :)

Code: Select all


/* atan(k * tan(t)), but handles quadrants properly */
double kaytan(double k, double t)
{
    return atan2(k * sin(t), cos(t));
}

//.................................

    /* Altitude & Azimuth */
    Mm = kaytan(1/cos(tr), decr);
    azi = kaytan(cos(Mm) / sin(latr - Mm), tr);
    cazi = cos(azi);
    coalt = kaytan(1/cazi, latr - Mm);


All angles are in radians.
latr: latitude
decr: solar declination
azi: azimuth
coalt: the complement of the altitude
tr: Local Apparent Time, also in radians.

User avatar
robby hobby
Posts: 5
Joined: Tue Nov 03, 2009 1:59 am UTC
Location: portland, or

Re: The "IT DOESN'T WORK!" thread

Postby robby hobby » Mon Dec 30, 2013 3:25 am UTC

Brilliant! Pm 2ring
I need to locate this USNO algorithm you sourced, my NOAA formula for azimuth θ is
cos(θ) = x (where x is a bunch of trig)
For a sec I was thinking I could sub using tan=sin/cos, it doesn't seem to work, θ = atan2(sinθ, x)
PM 2ring do you remember what the variable Mm is for?
I rewrote your code in expanded form with the kaytan function, I can't see a resemblance yet to my NOAA function.
Thanks for your help!, I'm on vacation with an ipad, I'll be back on my computer in a week and can start coding again.

Thanks, Thoughtfully, if I can't implement this myself I'm going to look into this. I really want to get it myself if possible
Robby

User avatar
PM 2Ring
Posts: 3619
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Re: The "IT DOESN'T WORK!" thread

Postby PM 2Ring » Thu Jan 02, 2014 11:06 am UTC

robby hobby wrote:PM 2ring do you remember what the variable Mm is for?


Sorry, I don't remember where that name comes from. :oops: But my code only uses it in the lines I posted earlier.

I got the Sun position formula from the USNO's Explanatory Supplement to the Astronomical Ephemeris, IIRC, the copy I had access to was published in the 1980s. I suspect that more recently published formulas would be more accurate, eg the formulas in the Wikipedia article Position of the Sun look pretty good.

Aldarion
Posts: 133
Joined: Thu Jul 19, 2007 7:00 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby Aldarion » Mon Feb 03, 2014 7:33 pm UTC

In order to get perhaps a bit closer to solving this, I found a tool, available here, which may help me put a bound on the problem.
The thing is, the tool is just two .class files, with no manual or explanation how to run it.
All I know about the program is that it's supposed to get a .cnf file and spit out a number.
The developers were also kind enough not to leave any contact information whatsoever.
Now, I did study Java for my BA, but it was four years ago, and I haven't had any need to practice it. So for the last hour or so I've been trying to import these classes into a project in Eclipse in all kinds of ways to no avail, and anyway, even if I managed to do so, I've still got no idea how to run the gorram thing.

Any help would be appreciated.
I'm not good, I'm not nice, I'm just right.

User avatar
e^iπ+1=0
Much, much better than Gooder
Posts: 2061
Joined: Sun Feb 15, 2009 9:41 am UTC
Location: Chicago-ish

Re: The "IT DOESN'T WORK!" thread

Postby e^iπ+1=0 » Mon Feb 03, 2014 7:42 pm UTC

I searched the site of the uni that the creators are from for their names and managed to find contact info for the third guy: Roland Yap.
poxic wrote:You, sir, have heroic hair.
poxic wrote:I note that the hair is not slowing down. It appears to have progressed from heroic to rocking.

(Avatar by Sungura)

Aldarion
Posts: 133
Joined: Thu Jul 19, 2007 7:00 pm UTC

Re: The "IT DOESN'T WORK!" thread

Postby Aldarion » Tue Feb 04, 2014 8:05 pm UTC

e^iπ+1=0 wrote:I searched the site of the uni that the creators are from for their names and managed to find contact info for the third guy: Roland Yap.


Thank you! Hope he still remembers how to run it.
I'm not good, I'm not nice, I'm just right.

User avatar
Diadem
Posts: 5649
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: The "IT DOESN'T WORK!" thread

Postby Diadem » Wed Feb 05, 2014 9:01 am UTC

Ok this is a very specific c++ question, and a pretty advanced one (none of my colleagues knew the answer). Perhaps someone here can help.

I have a template function that reads a variable of the template type from an object (containing JSON data).

Code: Select all

template <typename T>
T getvalue(Object x) {
    ... get data of type T from x ...
}


So it's a template function where the template parameter shows up in the return type and function body, but not in the parameter list (not 100% sure that is important, but I figured I'd best be complete).

Now, I want to make a template specialization. Specializing <int> for example would be easy.

Code: Select all

template <>
int getvalue(Object x) {
    ... get data of type int from x ...
}


However what I want is a specialization for vectors. But vectors are themselves a templated type. I can easily make a specialization for a specific type of vector. For example

Code: Select all

template <>
vector<int> getvalue(Object x) {
    ... get data of type vector<int> from x ...
}


But how do I make a specialization for all types of vectors? I can't figure it out. I did try Google of course before posting here, and I get a lot of results of people asking similar questions, but most of the answers seem either confused or horribly complicated. A lot of search results I got talked about the difference between partial and full template specialization, but I haven't been able to find a clear description of what exactly the difference between those two is, nor is it clear if this has anything to do with what I'm trying to do.

..............

A related question, something strange I discovered while investigating the above. Take the following code:

Code: Select all

template <typename T>
T testfunction(T t) {
    return t;
}

template <>
int testfunction<int> (int t) {
    return 3;
}

template <>
int testfunction<double> (double t) {
    return 4;
}

The first two functions compile, but the third one does not. The error the compiler gives is: "error C2785: 'T testfunction(T)' and 'int testfunction(double)' have different return types ". So that's not allowed. But why? I keep staring at that error message and thinking "So what? Who gives a damn".
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests