Welcome, Guest. Please login or register.
April 16, 2024, 09:03:09 am

ballp.it is the community forum for The F Plus.

You're only seeing part of the forum conversation. To see more, register for an account. This will give you read-only access to nearly all the forums.

Topic: Thread.setTitle("Programmers Anonymous");  (Read 61240 times)

Zekka

  • I AM IN INTO MATHEMATICAL CALCULATIONS AND MANY METHODS USED IN THE STOCK MARKET
  • Paid
    • 872
    • 54
Thread.setTitle("Programmers Anonymous"); #60
Oh yeah, I get that. (By the way, Haskell has list comprehensions and they work much like Python list comprehensions.)

You can implement a letter-of-the-law for loop that has an initial value, an update, and a condition to check each iteration, and it looks something like this

for :: Monad m => a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m ()
for value condition update body
  | condition value = body value >> for (update value) condition update body
  | otherwise = return ()

main = for 0 (< 10) (+ 1) $ \i ->
  print i

It's not actually that useful in practice because usually people who want an actual for loop want the ability for that for loop to be able to assign variables defined outside the for loop, stuff like that, and because Haskell's type system is incredibly opinionated, you basically can't do that and get it right. (there is a tool called ST designed to help you do that sort of thing, but my opinion is that it sucks)

I hope I didn't mislead you! I was really just trying to say you don't have to use explicit recursion all the time. You really can't get normal for loops without sacrificing the type system and probably also the default laziness. If you really can't survive without for loops that can affect variables in the outer code, you will not like Haskell. (which is an OK stance to have)
« Last Edit: February 24, 2017, 09:59:01 pm by Zekka »

Ambious

  • Guest
Thread.setTitle("Programmers Anonymous"); #61
I really need to get into Lambda expressions.
They seem useful and I have no idea how to use them.

A Whirring Bone-White Gleech

  • fact-lord
  • Paid
  • I was in first place, you whore!
  • 720
  • 155
Thread.setTitle("Programmers Anonymous"); #62
I hope I didn't mislead you! I was really just trying to say you don't have to use explicit recursion all the time. You really can't get normal for loops without sacrificing the type system and probably also the default laziness. If you really can't survive without for loops that can affect variables in the outer code, you will not like Haskell. (which is an OK stance to have)
Zekka, February 24, 2017, 09:46:58 pm

No worries.  I'm just whining; I used common lisp a little for a class forever ago, and I'm starting to get the very strong impression that Haskell is going to be painful to use in all the ways that Common Lisp was painful to use.  It's interesting in a lot of ways, but I suspect it's also going to be an intensely frustrating experience to try to write a non-trivial program in a language that discourages me from mutating state.  I don't like it, and I wouldn't do it if wasn't required too.  This is not going to be a fun project. :(

On a happier note, I have learned two nifty things about Python.  I said a while ago that I wished Python had C#-like properties; I just learned that it actually does, and it has since forever, I just didn't know it.  I'm very happy about this!

Also, python 3.4 added Enums, which I have sorely missed.
Gyro
« Last Edit: February 25, 2017, 06:34:09 pm by Der Trommelngleech »

Zekka

  • I AM IN INTO MATHEMATICAL CALCULATIONS AND MANY METHODS USED IN THE STOCK MARKET
  • Paid
    • 872
    • 54
Thread.setTitle("Programmers Anonymous"); #63
I hope I didn't mislead you! I was really just trying to say you don't have to use explicit recursion all the time. You really can't get normal for loops without sacrificing the type system and probably also the default laziness. If you really can't survive without for loops that can affect variables in the outer code, you will not like Haskell. (which is an OK stance to have)
Zekka, February 24, 2017, 09:46:58 pm

No worries.  I'm just whining; I used common lisp a little for a class forever ago, and I'm starting to get the very strong impression that Haskell is going to be painful to use in all the ways that Common Lisp was painful to use.  It's interesting in a lot of ways, but I suspect it's also going to be an intensely frustrating experience to try to write a non-trivial program in a language that discourages me from mutating state.  I don't like it, and I wouldn't do it if wasn't required too.  This is not going to be a fun project. :(
Der Trommelngleech, February 25, 2017, 05:56:58 am

Haskell is more ideological than Common Lisp. It has some tools builtin to make easy cases of mutable state doable, but with hard cases of mutable state those tools may not help very much. Those tools all intimately involve the type system.

Once you understand monads, check out IORefs and State, which are both designed to help with that problem. (IORefs will be more familiar to you, but they are less popular for general use.) You can also try STRefs, but like I said, I think ST takes a strong stomach.

Easy cases of mutable state: you only need to track changes in one mutable value. That value may be a record (in which case State simulates a scope with mutable vars), or it may not be: it's up to you.

Hard cases of mutable state: different procedures need to track changes in different variables.

Emperor Jack Chick

  • he/him
  • Ridiculist
  • Metal tyrant from hell
  • 3,193
  • 666
Thread.setTitle("Programmers Anonymous"); #64
HOW TO INCREASE MY SKILLS?????!!!!??!?!?!?!?!?!

had my yearly review yesterday. boss is stoked that i've been spending most of my downtime refactoring and building out our automation test codebase, both on a test level and in an application framework manner. He wants to see me increase my skills in this arena, but i'm not sure what the best path forwards is for that. Framework is written in Protractor running angular JS (using the chai-as-promised assertion library).

My options as i see it are the following:
  • Help out my coworker who is building the our ipad automation framework (requiring me to learn ruby)
  • Do more work to learn web development and the concepts theirein
  • Spend time learning more core computing concepts. data structures, application management, stuff like that

Thoughts?

A Whirring Bone-White Gleech

  • fact-lord
  • Paid
  • I was in first place, you whore!
  • 720
  • 155
Thread.setTitle("Programmers Anonymous"); #65
Help out my coworker who is building the our ipad automation framework (requiring me to learn ruby)
jack chick, March 01, 2017, 11:22:36 am
This sounds like a thing that every employer on the planet would really like.  Ruby is also a widely-used language and learning it would not be bad.

Spend time learning more core computing concepts. data structures, application management, stuff like that
jack chick, March 01, 2017, 11:22:36 am
A solid grasp of best practices, common object-oriented techniques and design patterns never goes amiss.  But you've probably already taught yourself some of that.

A Whirring Bone-White Gleech

  • fact-lord
  • Paid
  • I was in first place, you whore!
  • 720
  • 155
Thread.setTitle("Programmers Anonymous"); #66
Jesus Christ, fuck fuck monads and fuck haskell.  This language is awful.

Edit: I don't want to keep making rage-posts, so I'm just going to edit this one every time I encounter something new.
This snippet works:
import Numeric.LinearAlgebra

main = do
    let m = (3><3) ([1..] :: [Double])
    let d = 0.5 :: Double
    let m' = 0.1 * m
    putStrLn (show m')
...but, this one won't compile:
import Numeric.LinearAlgebra

main = do
    let m = (3><3) ([1..] :: [Double])
    let d = 0.5 :: Double
    let m' = (0.1 / d) * m
    putStrLn (show m')

I repeat, fuck this god-awful, useless language.

like 5 minutes later, I've narrowed it down a little:
    let m' = (0.5          ) * (m :: Matrix Double) -- works
    let m' = (0.5 :: Double) * (m :: Matrix Double) -- doesn't
Why on earth that makes any difference, I have no clue.

I found out why it's that way, and it's incredibly stupid.  This is what ultimately works:
    let m' = cmap (*d) m


Edit 2: Space Leaks

A bunch of simple recurrent functions resulted in a joyous occasion in the process of learning Haskell: my very first "space leak"!  A "space leak" is the cutesy name for 'a tail-recursive function that doesn't get optimized into a loop, and keeps producing thunks for intermediate values until your system runs out of memory and dies'.  It's not exactly a memory leak, because the system hasn't lost the handle to that memory: in principle, if the computation finished, it would clean up all that memory and correctly terminate.  It just winds up at the same place: allocating an obscene amount of memory, possibly hanging your system.

The problem comes in part from one of the glorious selling-points of Haskell, it's lazyness; it turns out that that lazyness often sabotages building tail-recursive loop optimization.  The comical solution, which it's taken me more than a week to figure out, is: "use ! to mark every god damned thing in the function as strict", i.e. "not-lazy".  Doing that has changed my memory requirements from "reaching 12G and then hanging the system" to 50 Kb.  I guess I get to look forward to a glorious future of marking every production with ! in a desperate attempt to ask GHC to kindly not piss away all my system's memory.

Edit 3:

Speaking of: run time for a GRU: 55 minutes in Python, 129 minutes in Haskell.  I don't know why.

Edit 4:

Cabal.  On the down-side, Cabal took a lot of fighting to get working, and I kind of feel like I shouldn't have needed to set up Cabal and a local package repository just to enable profiling.  On the up-side, though, now that it's actually working, it is kind of cool, I have to admit.  `cabal repl` made getting a local-packages-aware interpreter pretty easy, I'm pretty grateful for that.
« Last Edit: July 17, 2017, 10:00:37 pm by A Gleech that is a False Movie »

EYE OF ZA

  • some people's reactions such as the fuck,the hell,wtf, or what the hell
  • Paid
  • I have a problem and then I have another problem
    • 2,572
    • 162
Thread.setTitle("Programmers Anonymous"); #67
That's my sister's opinion of Haskell, which she had to learn for a job because the start-up guys she was working for were dead-set on using Haskell with Yesod for their web application

Dirk Dammit

  • Paid
  • 57
  • 5
Thread.setTitle("Programmers Anonymous"); #68
I just finished a "fullstack developer course" in which I got a semi decent grasp on beginner front end development like css, javascript, and ruby, while backend development concepts such as mvc architecture still elude the hell out of me. I just had a phone interview yesterday with a company and they want me to, as closely as possible, replicate the appearance of a jpg image of a site, and it's got me kinda nervous.

As a side note I need to learn node.

edit: would you guys say this is bootstrap or a different framework?

http://i.imgur.com/YG7Z2z3.jpg
« Last Edit: April 12, 2017, 08:10:00 pm by Jeffbomb »

lazzer grardaion?

  • Paid
  • 703
  • 27
So, since I'm probably going to be looking for jobs in the not-too-distant future, I thought that I would try learning more coding, since that's something I don't have nearly as much experience in as I would like, and which seems to be pretty important for jobs that people might want to hire physics PhDs for. I did take some C programming back at undergrad, but I thought that python would be a good place to start, as the syntax seems a lot more manageable than other languages.

As a mini practice project, I decided to make a simulation of the Ising Model, which is a system that follows some very basic mathematical rules, and is fun to watch. So, my python code is this:

# This program is designed to simulate the 2D Ising model using Monte-Carlo
# methods.

import random
import copy
import math
import numpy as np
import matplotlib.animation as animation
import matplotlib.pyplot as plt

# This sets the number of steps per frame update.
steps = 500

# This sets the temp of the system. There's a phase transition
# from stable to chaotic around 2.7
temperature = float(input('Temperature? \n'))

# n sets size of the grid
n = 50

# The grid is then randomly laid out with +1 and -1 squares.
g = [[2*random.randint(0,1)-1 for i in range(1,n+1)] for j in range(1,n+1)]
def isingupdate(data):
    global g
    for l in range(1, steps):
        newg = g.copy()
        t = 0

        # Random locations on the grid are then selected.
        # The energy of the selected location is computed , and it checks if
        # the system can lower its energy by flipping the square
        # from + to - or vice-versa
        i = random.randint(1, n - 2)
        j = random.randint(1, n - 2)
        energy = -(g[i][j])*(g[i+1][j]+g[i-1][j]+g[i][j+1]+g[i][j-1])
        if energy > 0:
            g[i][j] = -g[i][j]
           
        # If the flip isn't energetically favorable, there's still a random
        # chance for it to happen, based on the energy and temperature.
        else:
            k = random.random()
            if math.log(k) < 2*energy/temperature:
                g[i][j] = -g[i][j]

        # Time is incremented, and the grid is updated with new values.
        t += 1
        mat.set_data(newg)
        g = newg

    return [mat]

# The figure and axes are initialized, and then told to update based on the
# rules defined above.

fig, ax = plt.subplots()
mat = ax.matshow(g)
ani = animation.FuncAnimation(fig, isingupdate, interval = 1, blit = True)
plt.show()


And it works and all, but it's pretty slow, and can seemingly only handle a couple hundred updates per second. On the other hand this simulation can handle about 500000 updates per second. Like, is python just not the appropriate language to try and do this kind of thing?

Turtle

  • [F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+][F+]
  • Paid
  • 496
  • 69
I write neither python nor javascript, so I'm not familiar with performance pitfalls in either, but I'd be pretty shocked if there was a 1000x difference between python and javascript.

Have you tried identifying the bottlenecks in your code by benchmarking individual components? My first thought is your random calls - standard random libraries tend to be slower than you'd expect. I also wonder if the animation library you're using is as quick as what he's using - have you tried simulating it without drawing?

Edit: I guess as long as I'm talking performance: I recently completely rewrote our unit testing framework in C# instead of (old ass language) and cut execution time from 15 minutes to 2 minutes. I'm a little bit happy about that.
« Last Edit: July 10, 2017, 09:06:32 pm by Turtle »

A Whirring Bone-White Gleech

  • fact-lord
  • Paid
  • I was in first place, you whore!
  • 720
  • 155
So, since I'm probably going to be looking for jobs in the not-too-distant future, I thought that I would try learning more coding, since that's something I don't have nearly as much experience in as I would like, and which seems to be pretty important for jobs that people might want to hire physics PhDs for. I did take some C programming back at undergrad, but I thought that python would be a good place to start, as the syntax seems a lot more manageable than other languages.

As a mini practice project, I decided to make a simulation of the Ising Model, which is a system that follows some very basic mathematical rules, and is fun to watch. So, my python code is this:

# This program is designed to simulate the 2D Ising model using Monte-Carlo
# methods.

import random
import copy
import math
import numpy as np
import matplotlib.animation as animation
import matplotlib.pyplot as plt

# This sets the number of steps per frame update.
steps = 500

# This sets the temp of the system. There's a phase transition
# from stable to chaotic around 2.7
temperature = float(input('Temperature? \n'))

# n sets size of the grid
n = 50

# The grid is then randomly laid out with +1 and -1 squares.
g = [[2*random.randint(0,1)-1 for i in range(1,n+1)] for j in range(1,n+1)]
def isingupdate(data):
    global g
    for l in range(1, steps):
        newg = g.copy()
        t = 0

        # Random locations on the grid are then selected.
        # The energy of the selected location is computed , and it checks if
        # the system can lower its energy by flipping the square
        # from + to - or vice-versa
        i = random.randint(1, n - 2)
        j = random.randint(1, n - 2)
        energy = -(g[i][j])*(g[i+1][j]+g[i-1][j]+g[i][j+1]+g[i][j-1])
        if energy > 0:
            g[i][j] = -g[i][j]
           
        # If the flip isn't energetically favorable, there's still a random
        # chance for it to happen, based on the energy and temperature.
        else:
            k = random.random()
            if math.log(k) < 2*energy/temperature:
                g[i][j] = -g[i][j]

        # Time is incremented, and the grid is updated with new values.
        t += 1
        mat.set_data(newg)
        g = newg

    return [mat]

# The figure and axes are initialized, and then told to update based on the
# rules defined above.

fig, ax = plt.subplots()
mat = ax.matshow(g)
ani = animation.FuncAnimation(fig, isingupdate, interval = 1, blit = True)
plt.show()


And it works and all, but it's pretty slow, and can seemingly only handle a couple hundred updates per second. On the other hand this simulation can handle about 500000 updates per second. Like, is python just not the appropriate language to try and do this kind of thing?
LancashireMcGee, July 10, 2017, 04:05:30 pm

I *think* you're setting mat at the wrong place.  You're doing it inside your 500-steps-per-frame, so you're actually setting (and re-rendering?) that display every single update.  And that could be super slow.  I moved it outside the inner loop, and it looks like it's a lot faster.

So, this:

        # Time is incremented, and the grid is updated with new values.
        t += 1
        #mat.set_data(newg)
        g = newg

    mat.set_data(newg)

    return [mat]

Also, to answer your question, yes, python is really slow; I've heard it said that it's something like 100x slower that compiled code.  While python is used pretty heavily in science, it's almost always used with  numpy, and something like PyDSTool or Theano.

Emperor Jack Chick

  • he/him
  • Ridiculist
  • Metal tyrant from hell
  • 3,193
  • 666
FOR PERFORMANCE I WRITE EVERYTHING IN ASSEMBLY


on a real note - maybe you wanna look into a linter. you're importing copy and numpy and never using either.

Zekka

  • I AM IN INTO MATHEMATICAL CALCULATIONS AND MANY METHODS USED IN THE STOCK MARKET
  • Paid
    • 872
    • 54
g.copy is probably very slow. it doesn't look like you ever use t or take advantage of newg?

for posterity, here's a hyperoptimized C version that gets 30mil steps per second on my computer. i tried microoptimizing the assembly but it didn't really help. be sure to compile for 64-bit!

#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define STEPS (1000 * 1000 * 100)
#define N 50
#define TEMPERATURE 2.7

// keep random numbers small so we don't lose cache for logs
#define NEWRAND_MAX 0x100
#define NEWRAND_MASK 0xff
#define newrand_int(low, high) (rand() % ((high) - (low)) + (low))
#define newrand() rand() & NEWRAND_MASK

typedef int64_t t_cell;

t_cell data[N][N];
char logs[NEWRAND_MAX][9];

// #define: avoid making extra calls
#define step_ising() { \
  int i = newrand_int(1, N - 2); \
  int j = newrand_int(1, N - 2); \
  int energy = (-data[i][j]) * (data[i + 1][j] + data[i - 1][j] + data[i][j + 1] + data[i][j - 1]); \
  if (energy > 0 || logs[newrand() & NEWRAND_MASK][energy + 4]) { \
    data[i][j] = -data[i][j]; \
  } \
}

void init_ising() {
  for (int x = 0; x < N; x++) {
    for (int y = 0; y < N; y++) {
      data[x][y] = (t_cell) (newrand() & 1);
    }
  }

  // precompute logs
  for (int i = 0; i < NEWRAND_MAX; i++) {
    for (int energy = -4; energy <= 4; energy++) {
      logs[i][energy + 4] = log(i/(float)NEWRAND_MAX) < 2 * energy/TEMPERATURE;
    }
  }
}

void main() {
  init_ising();

  clock_t start = clock();
  for (int i = 0; i < STEPS; i++) { step_ising(); }
  clock_t end = clock();

  printf("%f steps per second", STEPS/((float)(end - start)/CLOCKS_PER_SEC));
}

A Whirring Bone-White Gleech

  • fact-lord
  • Paid
  • I was in first place, you whore!
  • 720
  • 155
FOR PERFORMANCE I WRITE EVERYTHING IN ASSEMBLY


on a real note - maybe you wanna look into a linter. you're importing copy and numpy and never using either.
jack chick, July 11, 2017, 09:31:18 am

Honestly, I've never bothered with linters, although I mostly do academic programming, so.  FWIW, pylint exists, and VS Code will install it for you.  (VS Code is a super nice editor, btw.  It even works well on linux!)

Actually, kind of related to nothing but maybe useful, Spyder is a really grate python IDE for scientific computing.  I find that both Spyder and VS Code make really great python IDEs, if you're looking for one.